#if (FEATURE_MODE == 0)
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_hash.h"
#include "ctc_linklist.h"

#include "ctc_qos.h"
#include "ctc_packet.h"
#include "ctc_stats.h"
#include "sys_usw_diag.h"
#include "sys_usw_linkagg.h"
#include "sys_usw_nexthop_api.h"
#include "sys_usw_mchip.h"
#include "sys_usw_stats_api.h"
#include "sys_usw_register.h"
#include "usw/include/drv_common.h"

#define FIB_HOST0_CAM_NUM          ( 32 )
#define FIB_HOST1_CAM_NUM          ( 32 )
#define FLOW_HASH_CAM_NUM          ( 32 )
#define USER_ID_HASH_CAM_NUM       ( 32 )
#define MPLS_HASH_CAM_NUM        ( 64 )
#define XC_OAM_HASH_CAM_NUM        ( 128 )
#define LPM_TMM_INVALID_USED_MEM8K   8192
#define LPM_TMM_INVALID_USED_MEM16K   16384
#define LPM_TMM_INVALID_USED_MEM24K   24576
#define LPM_TMM_INVALID_USED_MEM32K   32768

#define LPM_TMM_INVALID_USED_MEM00(lchip)  (DRV_FROM_TMM(lchip)?8192:4096)
#define LPM_TMM_INVALID_USED_MEM01(lchip)  (DRV_FROM_TMM(lchip)?16384:8192)

#define LPM_TMM_INVALID_USED_MEM10(lchip)  (DRV_IS_TMM(lchip)?24576:12288)
#define LPM_TMM_INVALID_USED_MEM11(lchip)  (DRV_IS_TMM(lchip)?32768:16384)

#define LPM_AT_INVALID_USED_MEM10(lchip)  (20480)
#define LPM_AT_INVALID_USED_MEM11(lchip)  (24576)

extern uint32
drv_usw_ftm_memid_2_table(uint8 lchip, uint32 mem_id);
extern int32
sys_usw_dump_db_register_cb(uint8 lchip, uint8 module, CTC_DUMP_MASTER_FUNC fn);

typedef struct sys_diag_drop_hash_user_data_s
{
    uint8  lchip;
    uint8  sub_index;
    ctc_diag_drop_t * p_drop;
}sys_diag_drop_hash_user_data_t;

typedef struct sys_usw_diag_drop_pkt_node_s
{
    ctc_slistnode_t head;

    uint16 lport;
    uint16 reason;
    uint32 hash_seed;
    sal_time_t old_timestamp;
    sal_time_t timestamp;
    uint32 pkt_id;
    uint32 len;
    uint8* buf;
    uint16 src_port;
}sys_usw_diag_drop_pkt_node_t;

typedef struct sys_usw_diag_drop_info_s
{
    /* key */
    uint16 lport;  /* 0xFFFF means system drop stats */
    uint16 reason;

    /* data */
    uint64 count;/*drop-count*/
}sys_usw_diag_drop_info_t;

struct sys_usw_diag_lb_dist_s
{
    uint16    group_id;
    uint16    flag;
    uint16    member_num;
    ctc_diag_lb_info_t* info;
};
typedef struct sys_usw_diag_lb_dist_s sys_usw_diag_lb_dist_t;

struct tcam_bist_param_s
{
    uint32 type:4;
    uint32 index:16;
    uint32 pattern:4;
    uint32 round:4;
    uint32 step:4;

    uint32 lpm_id:4;
    uint32 req_num:4;
    uint32 rsv:24;
};
typedef struct tcam_bist_param_s tcam_bist_param_t;

struct tcam_bist_result_s
{
    sys_diag_tcam_bmp* p_bmp;
    uint16* err_entry_cnt;
    uint16  first_err_idx;
};
typedef struct tcam_bist_result_s tcam_bist_result_t;

sys_usw_diag_t* p_usw_diag_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};

#define DIAG_LOCK \
    if (p_usw_diag_master[lchip]->diag_mutex) sal_mutex_lock(p_usw_diag_master[lchip]->diag_mutex)
#define DIAG_UNLOCK \
    if (p_usw_diag_master[lchip]->diag_mutex) sal_mutex_unlock(p_usw_diag_master[lchip]->diag_mutex)

#define SYS_USW_DIAG_INIT_CHECK(lchip)  \
    do{                                 \
        LCHIP_CHECK(lchip);         \
        if (p_usw_diag_master[lchip] == NULL)    \
        { SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " Feature not initialized \n");\
          return CTC_E_NOT_INIT; } \
      }while(0)

#define _memory_bist
#define SYS_USW_DIAG_BIST_WAIT_TIME               (5000)
#define SYS_USW_DIAG_BIST_FLOW_RAM_SZ             (2048)
#define SYS_USW_DIAG_BIST_FLOW_RAM_INVALID_SZ     (1024)


#define SYS_USW_DIAG_BIST_RAM_SZ_1K               (1024)
#define SYS_USW_DIAG_BIST_RAM_SZ_512              (512)
#define SYS_USW_DIAG_BIST_RAM_SZ_2K               (2048)
#define SYS_USW_DIAG_BIST_RAM_SZ_256              (256)

#define SYS_USW_DIAG_BIST_FLOW_REQ_MEM     (DRV_TABLE_MAX_INDEX(lchip, FlowTcamBistReqFA_t))
#define SYS_USW_DIAG_BIST_LPM_REQ_MEM      (DRV_TABLE_MAX_INDEX(lchip, LpmTcamBistReq0FA_t))
#define SYS_USW_DIAG_BIST_CID_REQ_MEM      (DRV_TABLE_MAX_INDEX(lchip, IpeCidTcamBistReq_t))
#define SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM  (DRV_TABLE_MAX_INDEX(lchip, QMgrEnqTcamBistReqFa_t))

#define SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM      (DRV_TABLE_MAX_INDEX(lchip, ProgramLtidTcamBistReqFA_t))
#define SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM     (DRV_TABLE_MAX_INDEX(lchip,  EgrSclHashTcamBistReqFa_t))
#define SYS_USW_DIAG_BIST_EGRACL_REQ_MEM         (DRV_TABLE_MAX_INDEX(lchip,  EgressAclTcamBistReqFa_t))
#define SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM  (DRV_TABLE_MAX_INDEX(lchip, IpeHdrAdjRouterMacTcamBistReqFa_t))
#define SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM  (DRV_TABLE_MAX_INDEX(lchip, IpeHdrAdjUdfTcamBistReqFa_t))
#define SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM  (DRV_TABLE_MAX_INDEX(lchip, ProgramAclTcamBist0ReqFA_t))
#define SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM  (DRV_TABLE_MAX_INDEX(lchip, UserIdHashTcamBistReqFa_t))
#define SYS_USW_DIAG_BIST_USERID_REQ_MEM      (DRV_TABLE_MAX_INDEX(lchip, UserIdTcamBistReqFa_t))

/* AT */
#define SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM           (DRV_TABLE_MAX_INDEX(lchip, ProgramIngAclTcamBist0ReqFA_t))
#define SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM           (DRV_TABLE_MAX_INDEX(lchip, ProgramEgrAclTcamBist0ReqFA_t))
#define SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_REQ_MEM      (DRV_TABLE_MAX_INDEX(lchip, ProgramEgrAclLtidTcamBistReqFA_t))
#define SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_REQ_MEM      (DRV_TABLE_MAX_INDEX(lchip, ProgramIngAclLtidTcamBistReqFA_t))

typedef enum sys_usw_diag_bist_tcam_e
{
    SYS_USW_DIAG_BIST_FLOW_TCAM,
    SYS_USW_DIAG_BIST_LPM_TCAM,
    SYS_USW_DIAG_BIST_CID_TCAM,
    SYS_USW_DIAG_BIST_ENQUEUE_TCAM,

    SYS_USW_DIAG_BIST_TIDSELECT_TCAM,
    SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM,
    SYS_USW_DIAG_BIST_EGRACL_TCAM,
    SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM,
    SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM,
    SYS_USW_DIAG_BIST_PROGRAMACL_TCAM,
    SYS_USW_DIAG_BIST_USERIDHASH_TCAM,
    SYS_USW_DIAG_BIST_USERID_TCAM,

    SYS_USW_DIAG_BIST_LPM_TCAM0,
    SYS_USW_DIAG_BIST_LPM_TCAM1,
    SYS_USW_DIAG_BIST_LPM_TCAM2,

    SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM,      /*AT*/
    SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM,      /*AT*/
    SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM, /*AT */
    SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM, /*AT*/

    SYS_USW_DIAG_BIST_TCAM_MAX,

    SYS_USW_DIAG_BIST_SRAM,

    SYS_USW_DIAG_BIST_ALL
}sys_usw_diag_bist_tcam_t;

extern int32
sys_usw_qos_set_queue(uint8 lchip, ctc_qos_queue_cfg_t* p_que_cfg);

extern int32
sys_usw_qos_get_queue(uint8 lchip, ctc_qos_queue_cfg_t* p_que_cfg);

extern int32
sys_usw_qos_set_shape(uint8 lchip, ctc_qos_shape_t* p_shape);

extern int32
sys_usw_packet_tx(uint8 lchip, ctc_pkt_tx_t* p_pkt_tx);

extern int32
sys_usw_packet_rx_register(uint8 lchip, ctc_pkt_rx_register_t* p_register);


extern int32
sys_usw_packet_rx_unregister(uint8 lchip, ctc_pkt_rx_register_t* p_register);

extern int32
sys_usw_packet_rx_unregister(uint8 lchip, ctc_pkt_rx_register_t* p_register);

extern int32
sys_usw_diag_drop_pkt_sync(ctc_pkt_rx_t* p_pkt_rx);

extern int32
sys_usw_oam_get_used_key_count(uint8 lchip, uint32* count);
extern int32
sys_usw_ipuc_get_tcam_memusage(uint8 lchip, uint8 sub_type, uint32* total_size, uint32* used_size);
extern int32
sys_usw_ftm_process_callback(uint8 lchip, uint32 spec_type, sys_ftm_specs_info_t* specs_info);
extern int32
sys_usw_aps_ftm_cb(uint8 lchip, uint32 *entry_num);
extern int32
sys_usw_acl_get_resource_by_priority(uint8 lchip, uint8 priority, uint8 dir, uint32*total, uint32* used);
extern int32
sys_usw_scl_get_resource_by_priority(uint8 lchip, uint8 dir, uint8 is_hash, uint8 priority, uint32*total, uint32* used);
extern int32
_sys_tm_diag_bist_trigger_write_control_wrapper(uint8 lchip, sys_usw_diag_bist_tcam_t type,uint8  test_pattern,uint32 index,uint8  step,uint8 is_clear,uint8 req_num);
extern int32
sys_usw_queue_traverse_queue_node(uint8 lchip, uint16 lport,
                                      int32 (*fn)(uint8 lchip, sys_traverse_t* data),
                                      void* user_data);
STATIC int32
_sys_usw_diag_tcam_io(uint8 lchip, uint32 index, uint32 cmd, void* val)
{
    uint32 new_index = 0;

    new_index = index;

    return DRV_IOCTL(lchip, new_index, cmd, val);
}

STATIC int32
_sys_usw_diag_table_str_to_upper(char* str)
{
    uint32  i = 0;
    /* convert the alphabets to upper case before comparison */
    for (i = 0; i < sal_strlen((char*)str); i++)
    {
        if (sal_isalpha((int32)str[i]) && sal_islower((int32)str[i]))
        {
            str[i] = sal_toupper(str[i]);
        }
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_table_is_hash_key(uint8 lchip, uint32 tbl_id)
{
    uint8 module = 0;
    if (drv_acc_get_hash_module(lchip, tbl_id, &module) < 0)
    {
        return 0;
    }
    return 1;
}

STATIC int32
_sys_usw_diag_table_acc_read(uint8 lchip, uint32 tbl_id, uint32 index, void *p_data)
{
    int32 ret = CTC_E_NONE;

    drv_acc_in_t  in;
    drv_acc_out_t out;

    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));

    in.type = DRV_ACC_TYPE_LOOKUP;
    in.tbl_id = tbl_id;
    in.index = index;
    in.op_type = DRV_ACC_OP_BY_INDEX;
    drv_acc_get_hash_module(lchip, in.tbl_id, &in.module);
    ret = drv_acc_api(lchip, &in, &out);

    sal_memcpy((uint8*)p_data, (uint8*)(out.data), DRV_TABLE_ENTRY_SIZE(lchip, tbl_id));

    return ret;
}

STATIC int32
_sys_usw_diag_table_acc_write(uint8 lchip, uint32 tbl_id, uint32 index, void *p_data)
{
    int32 ret = CTC_E_NONE;

    drv_acc_in_t  in;
    drv_acc_out_t out;

    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));

    in.type = DRV_ACC_TYPE_ADD;
    in.tbl_id = tbl_id;
    in.data = p_data;
    in.index = index;
    in.op_type = DRV_ACC_OP_BY_INDEX;
    drv_acc_get_hash_module(lchip, in.tbl_id, &in.module);
    ret = drv_acc_api(lchip, &in, &out);

    return ret;
}

uint32
_sys_usw_diag_drop_hash_make(sys_usw_diag_drop_info_t* node)
{
    return ctc_hash_caculate(sizeof(node->lport) + sizeof(node->reason), &(node->lport));
}

uint32
_sys_usw_diag_dist_hash_make(sys_usw_diag_lb_dist_t* node)
{
    return ctc_hash_caculate(sizeof(node->group_id)+sizeof(node->flag), &(node->group_id));
}

bool
_sys_usw_diag_drop_hash_cmp(sys_usw_diag_drop_info_t* stored_node, sys_usw_diag_drop_info_t* lkup_node)
{
    if (!stored_node || !lkup_node)
    {
        return FALSE;
    }
    if ((stored_node->lport == lkup_node->lport)
        && (stored_node->reason == lkup_node->reason))
    {
        return TRUE;
    }
    return FALSE;
}

bool
_sys_usw_diag_dist_hash_cmp(sys_usw_diag_lb_dist_t* stored_node, sys_usw_diag_lb_dist_t* lkup_node)
{
    if (!stored_node || !lkup_node)
    {
        return FALSE;
    }
    if ((stored_node->group_id == lkup_node->group_id)
        && (stored_node->flag == lkup_node->flag))
    {
        return TRUE;
    }
    return FALSE;
}

STATIC int32
_sys_usw_diag_free_drop_hash_data(void* node_data, void* user_data)
{
    sys_usw_diag_drop_info_t* info = (sys_usw_diag_drop_info_t*)node_data;
    if (info)
    {
        mem_free(info);
    }
    return 1;
}

STATIC int32
_sys_usw_diag_free_dist_hash_data(void* node_data, void* user_data)
{
    sys_usw_diag_lb_dist_t* info = (sys_usw_diag_lb_dist_t*)node_data;
    if (info)
    {
        if(info->info)
        {
            mem_free(info->info);
        }
        mem_free(info);
    }
    return CTC_E_NONE;
}

STATIC sys_usw_diag_drop_info_t*
_sys_usw_diag_drop_hash_lkup(uint8 lchip, uint16 lport, uint16 reason)
{
    sys_usw_diag_drop_info_t info;
    sal_memset(&info, 0, sizeof(sys_usw_diag_drop_info_t));
    info.lport = lport;
    info.reason = reason;
    return ctc_hash_lookup(p_usw_diag_master[lchip]->drop_hash, &info);
}

STATIC sys_usw_diag_lb_dist_t*
_sys_usw_diag_dist_hash_lkup(uint8 lchip, uint16 group_id, uint16 flag)
{
    sys_usw_diag_lb_dist_t info;
    sal_memset(&info, 0, sizeof(sys_usw_diag_lb_dist_t));
    info.group_id = group_id;
    info.flag = flag;
    return ctc_hash_lookup(p_usw_diag_master[lchip]->lb_dist, &info);
}

STATIC int32
_sys_usw_diag_drop_hash_add(uint8 lchip, sys_usw_diag_drop_info_t* info)
{
    sys_usw_diag_drop_info_t* node = NULL;
    
    node = mem_malloc(MEM_DIAG_MODULE, sizeof(sys_usw_diag_drop_info_t));
    if (NULL == node)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Add Drop Hash Info Fail. No Memory!\n");
        return CTC_E_NO_MEMORY;
    }
    sal_memcpy(node, info,sizeof(sys_usw_diag_drop_info_t));
    if (NULL == ctc_hash_insert(p_usw_diag_master[lchip]->drop_hash, node))
    {
        mem_free(node);
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Insert Drop Hash Info Fail. No Memory!\n");
        return CTC_E_NO_MEMORY;
    }
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_diag_drop_hash_remove(uint8 lchip, sys_usw_diag_drop_info_t* info)
{
    sys_usw_diag_drop_info_t* info_out = ctc_hash_remove(p_usw_diag_master[lchip]->drop_hash, (void*)info);
    if (NULL == info_out)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Remove Drop Hash Info Fail. Entry not exist!\n");
        return CTC_E_NOT_EXIST;
    }
    mem_free(info);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_dist_hash_add(uint8 lchip, sys_usw_diag_lb_dist_t* info)
{
    if (NULL == ctc_hash_insert(p_usw_diag_master[lchip]->lb_dist, info))
    {
        return CTC_E_NO_MEMORY;
    }

    return CTC_E_NONE;
}
STATIC int32
_sys_usw_diag_dist_hash_remove(uint8 lchip, sys_usw_diag_lb_dist_t* info)
{
    sys_usw_diag_lb_dist_t* info_out = ctc_hash_remove(p_usw_diag_master[lchip]->lb_dist, (void*)info);
    if (NULL == info_out)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Remove Drop Hash Info Fail. Entry not exist!\n");
        return CTC_E_NOT_EXIST;
    }
    if(info->info)
    {
       mem_free(info->info);
    }
    mem_free(info);
    return CTC_E_NONE;
}
int32
sys_usw_diag_drop_hash_update_count(uint8 lchip, uint16 lport, uint16 reason, uint64 count)
{
    sys_usw_diag_drop_info_t info_temp;
    sys_usw_diag_drop_info_t* info = NULL;
    sys_usw_diag_drop_info_t* temp = NULL;
    uint8 discard_type_dir = 0;
    uint8 clear_on_read = 0;

    if (MCHIP_MISC(lchip)->get_drop_resson_info)
    {
        MCHIP_MISC(lchip)->get_drop_resson_info(reason, &discard_type_dir, &clear_on_read);
    }
    if(0 == count && clear_on_read)
    {
        return CTC_E_NONE;
    }

    info = _sys_usw_diag_drop_hash_lkup(lchip, lport, reason);
    if(info)
    {
        temp = info;
    }
    else
    {
        temp = &info_temp;
    }
    sal_memset(&info_temp, 0, sizeof(sys_usw_diag_drop_info_t));
    temp->lport = lport;
    temp->reason = reason;
    if(clear_on_read)
    {
        temp->count += count;
    }
    else
    {
        temp->count = count;
    }
    if(NULL == info && 0 != count)     
    {
        CTC_ERROR_RETURN(_sys_usw_diag_drop_hash_add(lchip, temp));
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_drop_pkt_clear_buf(uint8 lchip)
{
    ctc_slistnode_t* node = NULL;
    ctc_slistnode_t* next_node = NULL;

    CTC_SLIST_LOOP_DEL(p_usw_diag_master[lchip]->drop_pkt_list, node, next_node)
    {
        ctc_slist_delete_node(p_usw_diag_master[lchip]->drop_pkt_list, node);
        mem_free(((sys_usw_diag_drop_pkt_node_t*)node)->buf);
        mem_free(node);
    }
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_diag_pkt_trace_watch_key_check(uint8 lchip, ctc_diag_pkt_trace_t* p_trace)
{
    ctc_xdata_t* p_xdata;
    if ((p_trace->mode != CTC_DIAG_TRACE_MODE_USER)
        && (p_trace->mode != CTC_DIAG_TRACE_MODE_NETWORK))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Packet Trace Mode Error! \n");
        return CTC_E_INVALID_PARAM;
    }

    if (p_trace->watch_point >= CTC_DIAG_TRACE_POINT_MAX)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Watch Point Error! \n");
        return CTC_E_INVALID_PARAM;
    }

    if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_CHANNEL)
        && (p_trace->watch_key.channel >= MCHIP_CAP(SYS_CAP_CHANNEL_NUM)))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Watch Key Channel Invalid! \n");
        return CTC_E_INVALID_PARAM;
    }
    if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_SRC_LPORT)
        && (p_trace->watch_key.src_lport >= MCHIP_CAP(SYS_CAP_SPEC_MAX_PORT_NUM)))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Watch Key SrcLport Invalid! \n");
        return CTC_E_INVALID_PARAM;
    }

    if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_XDATA))
    {
        p_xdata = p_trace->watch_key.xdata;
        if(!p_xdata || !p_xdata->fields || 1 != p_xdata->num || p_xdata->fields[0].width != CTC_XDATA_WIDTH_4 ||
           0 != p_xdata->fields[0].offset% CTC_XDATA_WIDTH_4 ||
           16 <= p_xdata->fields[0].data || CTC_CONST128 < (p_xdata->fields[0].width+p_xdata->fields[0].offset))
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Watch Key xData Invalid! \n");
            return CTC_E_INVALID_PARAM;
        }
    }

    return CTC_E_NONE;
}

uint8
_sys_usw_diag_pkt_trace_decode_pkt_id(uint8 lchip, uint32 pkt_id, ctc_pkt_tx_t*  pkt_tx)
{
    uint8 find = 0;
    uint8 gchip = 0;
    ctc_slistnode_t* node = NULL;
    sys_usw_diag_drop_pkt_node_t* drop_node = NULL;

    if (!pkt_id)
    {
        return 0;
    }
    sys_usw_get_gchip_id(lchip, &gchip);

    CTC_SLIST_LOOP(p_usw_diag_master[lchip]->drop_pkt_list, node)
    {
        drop_node = (sys_usw_diag_drop_pkt_node_t*)node;
        if (pkt_id == drop_node->pkt_id)
        {
            find = 1;
            pkt_tx->skb.data = drop_node->buf;
            pkt_tx->skb.len = drop_node->len;
            pkt_tx->tx_info.src_port = CTC_MAP_LPORT_TO_GPORT(gchip, drop_node->lport);
            pkt_tx->tx_info.dest_gport = CTC_MAP_LPORT_TO_GPORT(gchip, drop_node->src_port);
            break;
        }
    }

    if (!find)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not Found PacketId:%d \n", pkt_id);
    }
    return find;
}


STATIC int32
_sys_usw_diag_trigger_pkt_trace(uint8 lchip, ctc_diag_pkt_trace_t* p_trace)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 value = 0;
    ctc_pkt_tx_t*  pkt_tx = NULL;
    uint8 tx_valid = 1;
    sys_port_info_t p_port_info;
    sal_memset(&p_port_info, 0, sizeof(sys_port_info_t));

    if (p_trace->mode == CTC_DIAG_TRACE_MODE_USER)
    {
        if (MCHIP_DIAG(lchip)->set_dbg_session)
        {
            CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->set_dbg_session(lchip, p_trace));
        }
        if (DRV_IS_TSINGMA(lchip) && (SYS_GET_CHIP_VERSION != SYS_CHIP_SUB_VERSION_A))
        {
        /* bug 115434 drop cpu debug packet*/
            value = 1;
            cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_cpuVisibilityEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        }
        /* Packet Tx */
        pkt_tx = mem_malloc(MEM_DIAG_MODULE, sizeof(ctc_pkt_tx_t));
        if (NULL == pkt_tx)
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "No memory! \n");
            return CTC_E_NO_MEMORY;
        }
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Packet Trace Mode: User! Len: %d Src_port:0x%.4x\n", p_trace->pkt.user.len, p_trace->pkt.user.src_port);
        sal_memset(pkt_tx, 0, sizeof(ctc_pkt_tx_t));
        pkt_tx->lchip = lchip;
        pkt_tx->mode = CTC_PKT_MODE_DMA;
        if (0 == _sys_usw_diag_pkt_trace_decode_pkt_id(lchip, p_trace->pkt.user.pkt_id, pkt_tx))
        {
            pkt_tx->skb.data = p_trace->pkt.user.pkt_buf;
            pkt_tx->skb.len = p_trace->pkt.user.len;
            pkt_tx->tx_info.src_port = p_trace->pkt.user.src_port;
            pkt_tx->tx_info.dest_gport = p_trace->pkt.user.src_port;
        }
        pkt_tx->tx_info.flags = CTC_PKT_FLAG_SRC_PORT_VALID | CTC_PKT_FLAG_INGRESS_MODE | CTC_PKT_FLAG_DIAG_PKT;
        if(DRV_FROM_AT(lchip))
        {
            tx_valid = p_trace->pp_bmp || (CTC_E_NONE == sys_usw_port_api_get_com_info(lchip,CTC_MAP_GPORT_TO_LPORT(pkt_tx->tx_info.src_port), 0, &p_port_info) &&
                        lchip == SYS_PP_BASE(lchip)+p_port_info.pp_id);
        }
        if(tx_valid)
        {
            ret = sys_usw_packet_tx(lchip, pkt_tx);
        }
        mem_free(pkt_tx);
        return ret;
    }
    else if (MCHIP_DIAG(lchip)->set_dbg_pkt)
    {
        /* Network Key */
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Packet Trace Mode: Network!\n");
        CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->set_dbg_pkt(lchip, p_trace));
    }
    if (MCHIP_DIAG(lchip)->set_dbg_session)
    {
        CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->set_dbg_session(lchip, p_trace));
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_drop_hash_traverse_cb(sys_usw_diag_drop_info_t* info, void* user_data)
{
    sys_diag_drop_hash_user_data_t* p_user_data = user_data;
    ctc_diag_drop_t* p_drop = p_user_data->p_drop;
    uint16 drop_reason = 0;
    uint8  lchip = p_user_data->lchip;
    uint8  discard_type_dir = CTC_BOTH_DIRECTION;
    uint8  clear_on_read;

    CTC_PTR_VALID_CHECK(info);
    CTC_PTR_VALID_CHECK(p_drop);

    if (MCHIP_MISC(lchip)->get_drop_resson_info)
    {
        MCHIP_MISC(lchip)->get_drop_resson_info(info->reason, &discard_type_dir, &clear_on_read);
    }
    if(p_drop->dir != CTC_BOTH_DIRECTION && discard_type_dir != CTC_BOTH_DIRECTION && p_drop->dir != discard_type_dir)
    {
        return 0;
    }

    if (p_drop->oper_type == CTC_DIAG_DROP_OPER_TYPE_GET_PORT_BMP)
    {
        if (info->lport != SYS_DIAG_DROP_COUNT_SYSTEM)
        {
            CTC_BMP_SET(p_drop->u.port_bmp, info->lport);
        }
    }
    else if (p_drop->oper_type == CTC_DIAG_DROP_OPER_TYPE_GET_REASON_BMP)
    {
        if (p_drop->lport == info->lport)
        {
            if (MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc)
            {
                MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc(info->reason, &drop_reason);
            }
            CTC_BMP_SET(p_drop->u.reason_bmp, drop_reason);
        }
    }
    else
    {
        if (p_drop->lport != info->lport)
        {
            return 0;
        }
        if (MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc)
        {
            MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc(info->reason, &drop_reason);
        }
        if (p_drop->reason != drop_reason)
        {
            return 0;
        }
        p_drop->u.info.count += info->count;
        if (p_user_data->sub_index < p_drop->u.info.buffer_count)
        {
            sal_memset(&p_drop->u.info.buffer[p_user_data->sub_index],0,sizeof(ctc_diag_drop_info_buffer_t));
            p_drop->u.info.buffer[p_user_data->sub_index].sub_count = info->count;
            if (MCHIP_DIAG(lchip)->diag_get_pos)
            {
                CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->diag_get_pos(info->reason, &p_drop->u.info.buffer[p_user_data->sub_index].position));
            }
            if (NULL == MCHIP_DIAG(lchip)->get_discard_type_desc)
            {
                return CTC_E_NOT_SUPPORT;
            }
            sal_strncpy(p_drop->u.info.buffer[p_user_data->sub_index].sub_reason_desc, MCHIP_DIAG(lchip)->get_discard_type_desc(info->reason), CTC_DIAG_REASON_DESC_LEN-1);
            p_user_data->sub_index ++;
            p_drop->u.info.real_buffer_count ++;
        }

        if (p_drop->with_clear)
        {
            /* clear hash data */
            _sys_usw_diag_drop_hash_remove(lchip, info);
        }
    }
    return 0;
}

STATIC int32
_sys_usw_diag_get_drop_info(uint8 lchip, ctc_diag_drop_t* p_drop)
{
    uint16 drop_reason = 0;
    uint32 cp_len = 0;
    uint32 loop = 0;
    uint32 clear_cnt = 0;
    sys_usw_diag_drop_pkt_node_t* pkt_node = NULL;
    ctc_slistnode_t* node = NULL;
    ctc_slistnode_t* next_node = NULL;
    sys_diag_drop_hash_user_data_t user_data;


    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Oper_type:%d buffer_clear:%d\n", p_drop->oper_type, p_drop->with_clear);

    CTC_MAX_VALUE_CHECK(p_drop->dir, CTC_BOTH_DIRECTION);
    if (p_drop->oper_type > CTC_DIAG_DROP_OPER_TYPE_GET_DETAIL_INFO)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Oper_type Invalid! \n");
        return CTC_E_INTR_INVALID_PARAM;
    }
    if (p_drop->oper_type != CTC_DIAG_DROP_OPER_TYPE_GET_PORT_BMP)
    {
        if (p_drop->reason >= CTC_DROP_MAX)
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Reason Invalid! \n");
            return CTC_E_INVALID_CONFIG;
        }
        if ((p_drop->lport >= MCHIP_CAP(SYS_CAP_SPEC_MAX_PORT_NUM))
            && (p_drop->lport != SYS_DIAG_DROP_COUNT_SYSTEM))
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Lport Invalid! \n");
            return CTC_E_INVALID_CONFIG;
        }
    }
    if (MCHIP_DIAG(lchip)->get_drop_info)
    {
        CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->get_drop_info(lchip, (void*)p_drop));
    }
    sal_memset(&user_data, 0, sizeof(sys_diag_drop_hash_user_data_t));
    user_data.lchip = lchip;
    user_data.p_drop = p_drop;
    p_drop->u.info.real_buffer_count = 0;
    ctc_hash_traverse(p_usw_diag_master[lchip]->drop_hash, (hash_traversal_fn)_sys_usw_diag_drop_hash_traverse_cb, &user_data);

    switch (p_drop->oper_type)
    {
        case CTC_DIAG_DROP_OPER_TYPE_GET_PORT_BMP:
        case CTC_DIAG_DROP_OPER_TYPE_GET_REASON_BMP:
            break;
        case CTC_DIAG_DROP_OPER_TYPE_GET_DETAIL_INFO:
            if (p_drop->u.info.count == 0)
            {
                return CTC_E_NOT_EXIST;
            }
            sal_strncpy(p_drop->u.info.reason_desc, sys_usw_register_get_reason_desc(lchip, p_drop->reason), CTC_DIAG_REASON_DESC_LEN-1);
            loop = p_drop->u.info.real_buffer_count;
            CTC_SLIST_LOOP_DEL(p_usw_diag_master[lchip]->drop_pkt_list, node, next_node)
            {
                pkt_node =  _ctc_container_of(node, sys_usw_diag_drop_pkt_node_t, head);
                if (MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc)
                {
                    MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc(pkt_node->reason, &drop_reason);
                }
                else
                {
                    drop_reason = pkt_node->reason;
                }
                if ((pkt_node->lport != p_drop->lport) || (drop_reason != p_drop->reason))
                {
                    continue;
                }
                if ((0 == p_drop->u.info.buffer_count)
                    || (loop >= p_drop->u.info.buffer_count))
                {
                    break;
                }

                p_drop->u.info.buffer[loop].real_len = pkt_node->len;
                p_drop->u.info.buffer[loop].pkt_id = pkt_node->pkt_id;
                if (MCHIP_DIAG(lchip)->diag_get_pos)
                {
                    CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->diag_get_pos(pkt_node->reason, &p_drop->u.info.buffer[loop].position));
                }
                p_drop->u.info.buffer[loop].sub_count = 1;
                sal_strncpy(p_drop->u.info.buffer[loop].sub_reason_desc, MCHIP_DIAG(lchip)->get_discard_type_desc(pkt_node->reason), CTC_DIAG_REASON_DESC_LEN-1);

                cp_len = (pkt_node->len > p_drop->u.info.buffer[loop].len) ? p_drop->u.info.buffer[loop].len : pkt_node->len;
                sal_memcpy(&p_drop->u.info.buffer[loop].timestamp, &pkt_node->timestamp, sizeof(sal_time_t));
                sal_memcpy(p_drop->u.info.buffer[loop].pkt_buf, pkt_node->buf, cp_len * sizeof(uint8));
                if (p_drop->with_clear && (p_drop->u.info.buffer[loop].len >= pkt_node->len))
                {
                    ctc_slist_delete_node(p_usw_diag_master[lchip]->drop_pkt_list, node);
                    mem_free(pkt_node->buf);
                    mem_free(pkt_node);
                    clear_cnt++;
                }
                loop++;
            }
            p_drop->u.info.real_buffer_count = loop;
            break;
        default:
            break;
    }
    return CTC_E_NONE;
}

STATIC void
_sys_usw_diag_drop_pkt_report(uint8 lchip, ctc_pkt_rx_t* p_pkt_rx, uint32 pkt_id, sal_time_t timestamp)
{
    ctc_diag_drop_pkt_report_cb report_cb;
    uint32 pkt_len = 0;
    uint32 hdr_len = 0;
    uint32 report_len = 0;
    uint16 discard_type = 0;
    uint16 lport = 0;
    uint8  dir = CTC_INGRESS;


    lport = p_pkt_rx->rx_info.lport;
    if (p_pkt_rx->rx_info.ttl & 0x40)
    {
        /*EPE*/
        discard_type = (p_pkt_rx->rx_info.ttl & 0x3F)  + SYS_DIAG_DROP_REASON_BASE_EPE;
        dir = CTC_EGRESS;
    }
    else
    {
        /*IPE*/
        discard_type = p_pkt_rx->rx_info.ttl;
    }

    hdr_len = p_pkt_rx->eth_hdr_len + p_pkt_rx->pkt_hdr_len + p_pkt_rx->stk_hdr_len;
    pkt_len = p_pkt_rx->pkt_len - hdr_len - 4; /*without CRC Length (4 bytes)*/
    if (p_usw_diag_master[lchip]->drop_pkt_list)
    {
        report_len = (pkt_len > p_usw_diag_master[lchip]->drop_pkt_store_len) ? p_usw_diag_master[lchip]->drop_pkt_store_len : pkt_len;
    }
    else
    {
        report_len = pkt_len;
    }

    /* Packet Report */
    report_cb = p_usw_diag_master[lchip]->drop_pkt_report_cb;
    if (report_cb)
    {
        uint8 gchip = 0;
        int32 ret = CTC_E_NONE;
        char   reason_desc[CTC_DIAG_REASON_DESC_LEN];
        ctc_diag_drop_info_buffer_t pkt_buf;
        uint16 drop_reason = 0;
        sal_memset(&pkt_buf, 0, sizeof(pkt_buf));
        sys_usw_get_gchip_id(lchip, &gchip);
        pkt_buf.len = report_len;
        pkt_buf.real_len = report_len;
        pkt_buf.pkt_buf = p_pkt_rx->pkt_buf[0].data + hdr_len;
        pkt_buf.pkt_id = p_usw_diag_master[lchip]->drop_pkt_id;
        pkt_buf.timestamp = timestamp;
        pkt_buf.dir = dir;
        
        if (MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc)
        {
            MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc(discard_type, &drop_reason);
        }
        sal_strncpy(reason_desc, sys_usw_register_get_reason_desc(lchip, drop_reason), CTC_DIAG_REASON_DESC_LEN-1);
        DIAG_UNLOCK;
        ret = report_cb(CTC_MAP_LPORT_TO_GPORT(gchip, lport), drop_reason, reason_desc, &pkt_buf);
        DIAG_LOCK;
        if (ret < 0)
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Drop Packet Report Error, error=%d!\n", ret);
        }
    }
}

STATIC int32
_sys_usw_diag_drop_pkt_sync(uint8 lchip, ctc_pkt_rx_t* p_pkt_rx)
{
    uint16 lport = 0;
    uint16 reason = 0;
    uint32 hash_seed = 0;
    uint32 pkt_len = 0;
    uint32 hdr_len = 0;
    uint32 store_len = 0;
    uint32 hash_calc_len = 0;
    sal_time_t timestamp;
    ctc_slistnode_t*       node = NULL;
    sys_usw_diag_drop_pkt_node_t* pkt_node = NULL;

    if (!p_pkt_rx->buf_count)
    {
        return CTC_E_NONE;
    }

    sal_time(&timestamp);
    if (NULL == p_usw_diag_master[lchip]->drop_pkt_list)
    {
        p_usw_diag_master[lchip]->drop_pkt_id++;
        if (p_usw_diag_master[lchip]->drop_pkt_id == 0)
        {
            p_usw_diag_master[lchip]->drop_pkt_id++;
        }
        /*Report Packet*/
        _sys_usw_diag_drop_pkt_report(lchip, p_pkt_rx, p_usw_diag_master[lchip]->drop_pkt_id, timestamp);
        return CTC_E_NONE;
    }

    lport = p_pkt_rx->rx_info.lport;
    if (p_pkt_rx->rx_info.ttl & 0x40)
    {
        /*EPE*/
        reason = (p_pkt_rx->rx_info.ttl & 0x3F)  + SYS_DIAG_DROP_REASON_BASE_EPE;
    }
    else
    {
        /*IPE*/
        reason = p_pkt_rx->rx_info.ttl;
    }

    hdr_len = p_pkt_rx->eth_hdr_len + p_pkt_rx->pkt_hdr_len + p_pkt_rx->stk_hdr_len;
    pkt_len = p_pkt_rx->pkt_len - hdr_len - 4; /*without CRC Length (4 bytes)*/
    store_len = (pkt_len > p_usw_diag_master[lchip]->drop_pkt_store_len) ? p_usw_diag_master[lchip]->drop_pkt_store_len : pkt_len;

    /* hash key : packet */
    hash_calc_len = (store_len > p_usw_diag_master[lchip]->drop_pkt_hash_len) ? p_usw_diag_master[lchip]->drop_pkt_hash_len : store_len;
    hash_seed = ctc_hash_caculate(hash_calc_len, (void*)(p_pkt_rx->pkt_buf[0].data + hdr_len));
    CTC_SLIST_LOOP(p_usw_diag_master[lchip]->drop_pkt_list, node)
    {
        pkt_node = (sys_usw_diag_drop_pkt_node_t*)node;
        if ((hash_seed == pkt_node->hash_seed)
            && (store_len == pkt_node->len)
            && (lport == pkt_node->lport)
            && (reason == pkt_node->reason))
        {
            /*If the same drop packet time Interval >= 10min, report again*/
            if ((timestamp - pkt_node->old_timestamp) >= 10*60)
            {
                _sys_usw_diag_drop_pkt_report(lchip, p_pkt_rx, pkt_node->pkt_id, timestamp);
                /*Update Timestamp*/
                pkt_node->old_timestamp = timestamp;
            }
            pkt_node->timestamp = timestamp;
            /* means find the same packet */
            return CTC_E_NONE;
        }
    }

    p_usw_diag_master[lchip]->drop_pkt_id++;
    if (p_usw_diag_master[lchip]->drop_pkt_id == 0)
    {
        p_usw_diag_master[lchip]->drop_pkt_id++;
    }
    /*Drop Report, New Report*/
    _sys_usw_diag_drop_pkt_report(lchip, p_pkt_rx, p_usw_diag_master[lchip]->drop_pkt_id, timestamp);

    if (!p_usw_diag_master[lchip]->drop_pkt_store_cnt
        || ((p_usw_diag_master[lchip]->drop_pkt_list->count >= p_usw_diag_master[lchip]->drop_pkt_store_cnt)
        && (!p_usw_diag_master[lchip]->drop_pkt_overwrite)))
    {
        /* buffer exceed, and would not cover the oldest buffer */
        return CTC_E_NONE;
    }
    pkt_node = mem_malloc(MEM_DIAG_MODULE, sizeof(sys_usw_diag_drop_pkt_node_t));
    if (NULL == pkt_node)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Drop Packet Sync Error, No Memory!\n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(pkt_node, 0, sizeof(sys_usw_diag_drop_pkt_node_t));
    pkt_node->hash_seed = hash_seed;
    pkt_node->lport = lport;
    pkt_node->src_port = p_pkt_rx->rx_info.src_port;
    pkt_node->reason = reason;
    pkt_node->len = store_len;
    pkt_node->pkt_id = p_usw_diag_master[lchip]->drop_pkt_id;
    pkt_node->timestamp = timestamp;
    pkt_node->old_timestamp = timestamp;
    pkt_node->buf = mem_malloc(MEM_DIAG_MODULE, store_len);
    if (NULL == pkt_node->buf)
    {
        mem_free(pkt_node);
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Drop Packet Sync Error, No Memory!\n");
        return CTC_E_NO_MEMORY;
    }
    sal_memcpy(pkt_node->buf, p_pkt_rx->pkt_buf[0].data + hdr_len, store_len);
    if (p_usw_diag_master[lchip]->drop_pkt_list->count >= p_usw_diag_master[lchip]->drop_pkt_store_cnt)
    {
        sys_usw_diag_drop_pkt_node_t* node_temp = NULL;
        node = p_usw_diag_master[lchip]->drop_pkt_list->head;
        node_temp = (sys_usw_diag_drop_pkt_node_t*)node;
        /* buffer exceed, and cover the oldest buffer */
        ctc_slist_delete_node(p_usw_diag_master[lchip]->drop_pkt_list, node);
        /* free hash data */
        mem_free(node_temp->buf);
        mem_free(node_temp);
    }
    ctc_slist_add_tail(p_usw_diag_master[lchip]->drop_pkt_list, &pkt_node->head);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_drop_pkt_redirect_tocpu_en(uint8 lchip, uint8 dir, uint8 enable)
{
    ctc_qos_shape_t shape;
    ctc_qos_queue_cfg_t que_cfg;
    uint32 value = 0;
    uint32 cmd = 0;
    IpeFwdCtl_m ipe_fwd_ctl;
    EpeHeaderEditCtl_m epe_edit_ctl;

    sal_memset(&que_cfg, 0, sizeof(ctc_qos_queue_cfg_t));
    sal_memset(&shape, 0, sizeof(ctc_qos_shape_t));

    cmd = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_ctl));

    cmd = DRV_IOR(EpeHeaderEditCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_edit_ctl));
    if (enable)
    {
        /*first clear*/
        SetIpeFwdCtl(V, discardEventLogEn_f, &ipe_fwd_ctl, 0);
        SetEpeHeaderEditCtl(V, discardEventLogEn_f, &epe_edit_ctl, 0);
        SetIpeFwdCtl(V, discardPacketLogEn_f, &ipe_fwd_ctl, 0);
        SetEpeHeaderEditCtl(V, discardPacketLogEn_f, &epe_edit_ctl, 0);

        if (DRV_FROM_TMM(lchip))
        {
            uint32 discard_bmp[2] = {0x0, 0xFFFFFFFF}; /*ipe discard type 0, used for iLoop drop*/
            if(dir == CTC_INGRESS || dir == CTC_BOTH_DIRECTION)
            {
                discard_bmp[0] = (0xF7FFFFFE); /*epe discard type store in ttl, loop through ipe don't change ttl fater unset bit 27 */
                SetIpeFwdCtl(V, discardEventLogEn_f, &ipe_fwd_ctl, 1);
                SetIpeFwdCtl(V, discardEventLogWithDiscardType_f, &ipe_fwd_ctl, 1);
                SetIpeFwdCtl(A, discardEventLogEnBitmap_f, &ipe_fwd_ctl, discard_bmp);
            }
            
            if(dir == CTC_EGRESS || dir == CTC_BOTH_DIRECTION)
            {
                discard_bmp[0] = (0xFFFFFFFE);
                SetEpeHeaderEditCtl(V, discardEventLogEn_f, &epe_edit_ctl, 1);
                SetEpeHeaderEditCtl(V, discardEventLogWithDiscardType_f, &epe_edit_ctl, 1);
                SetEpeHeaderEditCtl(A, discardEventLogEnBitmap_f, &epe_edit_ctl, discard_bmp);
                value = GetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl);
                /* Set discardEventLogEn */
                CTC_BIT_SET(value, 7);
                SetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl, value);
            }
        }
        else
        {
            if(dir == CTC_INGRESS || dir == CTC_BOTH_DIRECTION)
            {
                SetIpeFwdCtl(V, discardPacketLogType_f, &ipe_fwd_ctl, 0x1C);/* all discard*/
                SetIpeFwdCtl(V, discardPacketLogEn_f, &ipe_fwd_ctl, 1);
                SetIpeFwdCtl(V, dropPktLogWithDiscardType_f, &ipe_fwd_ctl, 1);
            }
            /*EPE*/
            if(dir == CTC_EGRESS || dir == CTC_BOTH_DIRECTION)
            {
                SetEpeHeaderEditCtl(V, discardPacketLogEn_f, &epe_edit_ctl, 1);
                SetEpeHeaderEditCtl(V, dropPktLogWithDiscardType_f, &epe_edit_ctl, 1);
                SetEpeHeaderEditCtl(V, discardPacketLogType_f, &epe_edit_ctl, 1);
                value = GetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl);
                /* Set discardPacketLogEn */
                CTC_BIT_SET(value, 8);
                SetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl, value);
            }
        }
        cmd = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_ctl));
        cmd = DRV_IOW(EpeHeaderEditCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_edit_ctl));

        /*CTC_PKT_CPU_REASON_DIAG_DISCARD_PKT dest-to Local-CPU*/
        que_cfg.type = CTC_QOS_QUEUE_CFG_QUEUE_REASON_DEST;
        que_cfg.value.reason_dest.cpu_reason = CTC_PKT_CPU_REASON_DIAG_DISCARD_PKT;
        que_cfg.value.reason_dest.dest_type = CTC_PKT_CPU_REASON_TO_LOCAL_CPU;
        CTC_ERROR_RETURN(sys_usw_qos_set_queue(lchip, &que_cfg));

        /* Shape */
        shape.type = CTC_QOS_SHAPE_QUEUE;
        shape.shape.queue_shape.enable = 1;
        shape.shape.queue_shape.queue.queue_type = CTC_QUEUE_TYPE_EXCP_CPU;
        shape.shape.queue_shape.pir = 1000;/* 1M */
        shape.shape.queue_shape.pbs = 0xFFFFFFFF;
        shape.shape.queue_shape.queue.cpu_reason = CTC_PKT_CPU_REASON_DIAG_DISCARD_PKT;
        CTC_ERROR_RETURN(sys_usw_qos_set_shape(lchip, &shape));
    }
    else
    {
        if (DRV_FROM_TMM(lchip))
        {
            /*IPE*/
            uint32 discard_bmp[2] = {0};
            SetIpeFwdCtl(V, discardEventLogEn_f, &ipe_fwd_ctl, 0);
            SetIpeFwdCtl(V, discardEventLogWithDiscardType_f, &ipe_fwd_ctl, 0);
            SetIpeFwdCtl(A, discardEventLogEnBitmap_f, &ipe_fwd_ctl, discard_bmp);

            /*EPE*/
            SetEpeHeaderEditCtl(V, discardEventLogEn_f, &epe_edit_ctl, 0);
            SetEpeHeaderEditCtl(V, discardEventLogWithDiscardType_f, &epe_edit_ctl, 0);
            SetEpeHeaderEditCtl(A, discardEventLogEnBitmap_f, &epe_edit_ctl, discard_bmp);

            value = GetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl);
            /* Set discardEventLogEn */
            CTC_BIT_UNSET(value, 7);
            SetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl, value);
        }
        else
        {
            SetIpeFwdCtl(V, discardPacketLogType_f, &ipe_fwd_ctl, 0);/* all discard*/
            SetIpeFwdCtl(V, discardPacketLogEn_f, &ipe_fwd_ctl, 0);
            SetIpeFwdCtl(V, dropPktLogWithDiscardType_f, &ipe_fwd_ctl, 0);

            SetEpeHeaderEditCtl(V, discardPacketLogEn_f, &epe_edit_ctl, 0);
            SetEpeHeaderEditCtl(V, dropPktLogWithDiscardType_f, &epe_edit_ctl, 0);
            SetEpeHeaderEditCtl(V, discardPacketLogType_f, &epe_edit_ctl, 0);

            value = GetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl);
            /* Set discardPacketLogEn */
            CTC_BIT_UNSET(value, 8);
            SetEpeHeaderEditCtl(V, logOnDiscard_f, &epe_edit_ctl, value);
        }
        cmd = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_ctl));
        cmd = DRV_IOW(EpeHeaderEditCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_edit_ctl));

        que_cfg.type = CTC_QOS_QUEUE_CFG_QUEUE_REASON_DEST;
        que_cfg.value.reason_dest.cpu_reason = CTC_PKT_CPU_REASON_DIAG_DISCARD_PKT;
        CTC_ERROR_RETURN(sys_usw_qos_get_queue(lchip, &que_cfg));
        if(CTC_PKT_CPU_REASON_TO_DROP != que_cfg.value.reason_dest.dest_type)
        {
            shape.type = CTC_QOS_SHAPE_QUEUE;
            shape.shape.queue_shape.enable = 0;
            shape.shape.queue_shape.queue.queue_type = CTC_QUEUE_TYPE_EXCP_CPU;
            shape.shape.queue_shape.queue.cpu_reason = CTC_PKT_CPU_REASON_DIAG_DISCARD_PKT;
            CTC_ERROR_RETURN(sys_usw_qos_set_shape(lchip, &shape));

            que_cfg.type = CTC_QOS_QUEUE_CFG_QUEUE_REASON_DEST;
            que_cfg.value.reason_dest.cpu_reason = CTC_PKT_CPU_REASON_DIAG_DISCARD_PKT;
            que_cfg.value.reason_dest.dest_type = CTC_PKT_CPU_REASON_TO_DROP;
            CTC_ERROR_RETURN(sys_usw_qos_set_queue(lchip, &que_cfg));
        }
    }
    sys_usw_packet_tx_set_property(lchip, SYS_PKT_TX_TYPE_EPE_DISCARD_EN, enable, 0);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_drop_pkt_set_config(uint8 lchip, ctc_diag_drop_pkt_config_t* p_cfg)
{
    int32 ret = 0;
    uint8 need_free_list = 0;

    CTC_MAX_VALUE_CHECK(p_cfg->dir, CTC_BOTH_DIRECTION);
    if (p_cfg->flags & CTC_DIAG_DROP_PKT_HASH_CALC_LEN)
    {
        CTC_MAX_VALUE_CHECK(p_cfg->hash_calc_len,128);
    }
    if (p_cfg->flags & CTC_DIAG_DROP_PKT_CLEAR)
    {
        _sys_usw_diag_drop_pkt_clear_buf(lchip);
    }

    if (p_cfg->flags & CTC_DIAG_DROP_PKT_STORE_EN)
    {
        if (p_cfg->storage_en)
        {
            if (p_usw_diag_master[lchip]->drop_pkt_list)
            {
               goto report;
            }
            p_usw_diag_master[lchip]->drop_pkt_list = ctc_slist_new();
            if (NULL == p_usw_diag_master[lchip]->drop_pkt_list)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "No Memory! \n");
                return CTC_E_NO_MEMORY;
            }
            need_free_list = 1;
        }
        else if (p_usw_diag_master[lchip]->drop_pkt_list)
        {
            _sys_usw_diag_drop_pkt_clear_buf(lchip);
            ctc_slist_free(p_usw_diag_master[lchip]->drop_pkt_list);
            p_usw_diag_master[lchip]->drop_pkt_list = NULL;
        }
    }

report:
    if (p_cfg->flags & CTC_DIAG_DROP_PKT_REPORT_CALLBACK)
    {
        p_usw_diag_master[lchip]->drop_pkt_report_cb = p_cfg->report_cb;
    }

    if(((p_cfg->flags & CTC_DIAG_DROP_PKT_STORE_EN) && p_cfg->storage_en) ||
        ((p_cfg->flags & CTC_DIAG_DROP_PKT_REPORT_CALLBACK) && p_cfg->report_cb))
    {
        ret = (_sys_usw_diag_drop_pkt_redirect_tocpu_en(lchip, p_cfg->dir, 1));
    }
    else
    {
        ret = (_sys_usw_diag_drop_pkt_redirect_tocpu_en(lchip, p_cfg->dir, 0));
    }
    if(ret && need_free_list)
    {
        ctc_slist_delete(p_usw_diag_master[lchip]->drop_pkt_list);
        p_usw_diag_master[lchip]->drop_pkt_list = NULL;
        return ret;
    }
    if (p_cfg->flags & CTC_DIAG_DROP_PKT_HASH_CALC_LEN)
    {
        p_usw_diag_master[lchip]->drop_pkt_hash_len = p_cfg->hash_calc_len;
    }
    if (p_cfg->flags & CTC_DIAG_DROP_PKT_STORE_LEN)
    {
        p_usw_diag_master[lchip]->drop_pkt_store_len = p_cfg->storage_len;
    }
    if (p_cfg->flags & CTC_DIAG_DROP_PKT_STORE_NUM)
    {
        p_usw_diag_master[lchip]->drop_pkt_store_cnt = p_cfg->storage_num;
    }
    if (p_cfg->flags & CTC_DIAG_DROP_PKT_OVERWRITE)
    {
        p_usw_diag_master[lchip]->drop_pkt_overwrite = p_cfg->overwrite ? 1 : 0;
    }
    return ret;
}

STATIC int32
_sys_usw_diag_drop_pkt_get_config(uint8 lchip, ctc_diag_drop_pkt_config_t* p_cfg)
{
    IpeFwdCtl_m ipe_fwd_ctl;
    EpeHeaderEditCtl_m epe_edit_ctl;
    uint32 cmd = 0;
    
    p_cfg->hash_calc_len = p_usw_diag_master[lchip]->drop_pkt_hash_len;
    CTC_SET_FLAG(p_cfg->flags, CTC_DIAG_DROP_PKT_HASH_CALC_LEN);
    p_cfg->storage_len = p_usw_diag_master[lchip]->drop_pkt_store_len;
    CTC_SET_FLAG(p_cfg->flags, CTC_DIAG_DROP_PKT_STORE_LEN);
    p_cfg->storage_num = p_usw_diag_master[lchip]->drop_pkt_store_cnt;
    CTC_SET_FLAG(p_cfg->flags, CTC_DIAG_DROP_PKT_STORE_NUM);
    p_cfg->overwrite = p_usw_diag_master[lchip]->drop_pkt_overwrite ? TRUE : FALSE;
    CTC_SET_FLAG(p_cfg->flags, CTC_DIAG_DROP_PKT_OVERWRITE);
    p_cfg->storage_en = p_usw_diag_master[lchip]->drop_pkt_list ? TRUE : FALSE;
    CTC_SET_FLAG(p_cfg->flags, CTC_DIAG_DROP_PKT_STORE_EN);
    p_cfg->report_cb = p_usw_diag_master[lchip]->drop_pkt_report_cb;
    CTC_SET_FLAG(p_cfg->flags, CTC_DIAG_DROP_PKT_REPORT_CALLBACK);

    cmd = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_ctl));
    cmd = DRV_IOR(EpeHeaderEditCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_edit_ctl));
    if (DRV_FROM_TMM(lchip))
    {
        if(GetIpeFwdCtl(V, discardEventLogEn_f, &ipe_fwd_ctl) && GetEpeHeaderEditCtl(V, discardEventLogEn_f, &epe_edit_ctl))
        {
            p_cfg->dir = CTC_BOTH_DIRECTION;
        }
        else if(GetIpeFwdCtl(V, discardEventLogEn_f, &ipe_fwd_ctl))
        {
            p_cfg->dir = CTC_INGRESS;
        }
        else if(GetEpeHeaderEditCtl(V, discardEventLogEn_f, &epe_edit_ctl))
        {
            p_cfg->dir = CTC_EGRESS;
        }
    }
    else
    {
        if(GetIpeFwdCtl(V, discardPacketLogEn_f, &ipe_fwd_ctl) && GetEpeHeaderEditCtl(V, discardPacketLogEn_f, &epe_edit_ctl))
        {
            p_cfg->dir = CTC_BOTH_DIRECTION;
        }
        else if(GetIpeFwdCtl(V, discardPacketLogEn_f, &ipe_fwd_ctl))
        {
            p_cfg->dir = CTC_INGRESS;
        }
        else if(GetEpeHeaderEditCtl(V, discardPacketLogEn_f, &epe_edit_ctl))
        {
            p_cfg->dir = CTC_EGRESS;
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_set_property(uint8 lchip,ctc_diag_property_t prop, void* p_value)
{
    switch (prop)
    {
        case CTC_DIAG_PROP_DROP_PKT_CONFIG:
            CTC_ERROR_RETURN(_sys_usw_diag_drop_pkt_set_config(lchip, (ctc_diag_drop_pkt_config_t*)p_value));
        default:
            break;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_get_property(uint8 lchip,ctc_diag_property_t prop, void* p_value)
{
    switch (prop)
    {
        case CTC_DIAG_PROP_DROP_PKT_CONFIG:
            CTC_ERROR_RETURN(_sys_usw_diag_drop_pkt_get_config(lchip, (ctc_diag_drop_pkt_config_t*)p_value));
        default:
            break;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_diag_drop_hash_traverse_dump(sys_usw_diag_drop_info_t* info, sys_traverse_t*  p_para)
{
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_para->value1;
#endif
    CTC_PTR_VALID_CHECK(p_para)
    CTC_PTR_VALID_CHECK(info);
    SYS_DUMP_DB_LOG((sal_file_t)p_para->data, "%.4d   %.4d    %"PRId64"\n", info->lport, info->reason, info->count);
    return 0;
}

STATIC int32
_sys_usw_diag_dump_db(uint8 lchip, sal_file_t p_f,ctc_global_dump_db_t* p_dump_param)
{
    sys_traverse_t  para;

    SYS_USW_DIAG_INIT_CHECK(lchip);
    DIAG_LOCK;
    SYS_DUMP_DB_LOG(p_f, "%s\n", "# DIAG");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-36s: %s\n","Storage drop packet", p_usw_diag_master[lchip]->drop_pkt_list ? "Enable" : "Disable");
    SYS_DUMP_DB_LOG(p_f, "%-36s: %s\n","Report drop packet", p_usw_diag_master[lchip]->drop_pkt_report_cb ? "Enable" : "Disable");
    SYS_DUMP_DB_LOG(p_f, "%-36s: %s\n","Cover exceed", p_usw_diag_master[lchip]->drop_pkt_overwrite ? "Enable" : "Disable");
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Hash calc length", p_usw_diag_master[lchip]->drop_pkt_hash_len);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Storage packet count", p_usw_diag_master[lchip]->drop_pkt_store_cnt);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Storage packet length", p_usw_diag_master[lchip]->drop_pkt_store_len);
    SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------");

    if (p_usw_diag_master[lchip]->drop_hash->count)
    {
        SYS_DUMP_DB_LOG(p_f, "\n");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "##Drop Statistics");
        SYS_DUMP_DB_LOG(p_f, "%-5s  %-6s  %-10s\n", "Lport", "Reason", "Statistics");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------");
        sal_memset(&para, 0, sizeof(sys_traverse_t));
        para.data = (void*)p_f;
        para.value1 = lchip;
        ctc_hash_traverse(p_usw_diag_master[lchip]->drop_hash, (hash_traversal_fn)_sys_usw_diag_drop_hash_traverse_dump, &para);
        SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------");
    }
    if (p_usw_diag_master[lchip]->drop_pkt_list && p_usw_diag_master[lchip]->drop_pkt_list->count)
    {
        uint32 loop = 0;
        uint32 index = 0;
        ctc_slistnode_t* node = NULL;
        sys_usw_diag_drop_pkt_node_t* pkt_node = NULL;
        SYS_DUMP_DB_LOG(p_f, "\n");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "##Drop Packet");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
        CTC_SLIST_LOOP(p_usw_diag_master[lchip]->drop_pkt_list, node)
        {
            pkt_node = (sys_usw_diag_drop_pkt_node_t*)node;
            SYS_DUMP_DB_LOG(p_f,"%-20s:%d\n", "Index", loop);
            SYS_DUMP_DB_LOG(p_f,"%-20s:%d\n", "PktId", pkt_node->pkt_id);
            SYS_DUMP_DB_LOG(p_f,"%-20s:%d\n", "Lport", pkt_node->lport);
            SYS_DUMP_DB_LOG(p_f,"%-20s:%d\n", "Reason", pkt_node->reason);
            SYS_DUMP_DB_LOG(p_f,"%-20s:0x%x\n", "Hashseed", pkt_node->hash_seed);
            SYS_DUMP_DB_LOG(p_f,"%-20s:%s", "Timestamp", sal_ctime(&pkt_node->timestamp));
            SYS_DUMP_DB_LOG(p_f,"%-20s:%s", "Old_Timestamp", sal_ctime(&pkt_node->old_timestamp));
            SYS_DUMP_DB_LOG(p_f, "%s\n", "-------------------------------------------------");
            for (index = 0; index < pkt_node->len; index++)
            {
                if (index % 16 == 0)
                {
                    SYS_DUMP_DB_LOG(p_f, "0x%.4x:  ", index / 16 * 16);
                }
                SYS_DUMP_DB_LOG(p_f, "%.2x", pkt_node->buf[index]);
                if (index % 2)
                {
                    SYS_DUMP_DB_LOG(p_f," ");
                }
                if ((index + 1) % 16 == 0)
                {
                    SYS_DUMP_DB_LOG(p_f,"\n");
                }
            }
            SYS_DUMP_DB_LOG(p_f, "\n\n");
            loop++;
        }
    }

    DIAG_UNLOCK;
    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");
    return CTC_E_NONE;
}

#define SYS_DIAG_TBL_SKIP_CHK(tbl_id) (DsL2Edit3WOuter_t != tbl_id && DsL3Edit3W3rd_t != tbl_id)
#define SYS_DIAG_TBL_ID_CONVERT(in, out) \
    if (DsL2Edit3WOuter_t == in){\
        out = DRV_FROM_TMM(lchip)? DsL2EditAddEth1X_t: DsL2EditEth3W_t;\
    }else if (DsL3Edit3W3rd_t == in) {\
        out = DRV_FROM_TMM(lchip)? DsL3EditAddMpls1X_t: DsL3EditMpls3W_t;\
    } else{ out = in; }


STATIC int32
_sys_usw_diag_read_tbl(uint8 lchip, ctc_diag_tbl_t *p_para)
{
    char* tbl_name = NULL;
    uint32 tbl_id = 0;
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    tbl_entry_t entry;
    uint32* data_entry = NULL;
    uint32* mask_entry = NULL;
    int32 i = 0;
    uint32 index = 0;
    uint32 index_temp = 0;
    uint32 is_half = 0;
    fields_t* fld_ptr = NULL;
    tables_info_t* tbl_ptr = NULL;
    uint32 field_id = 0;
    uint32 field_cnt = 0;
    uint32 loop = 0;
    char fld_name[CTC_DIAG_TBL_NAME_SIZE] = {0};
    uint32 tbl_id_tmp = 0;

    data_entry = (uint32*)mem_malloc(MEM_DIAG_MODULE,MAX_ENTRY_WORD * sizeof(uint32));
    if(NULL == data_entry)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% No memory\n");
        return CTC_E_NO_MEMORY;
    }

    mask_entry = (uint32*)mem_malloc(MEM_DIAG_MODULE,MAX_ENTRY_WORD * sizeof(uint32));
    if(NULL == mask_entry)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% No memory\n");
        mem_free(data_entry);
        return CTC_E_NO_MEMORY;
    }
    sal_memset(data_entry, 0, MAX_ENTRY_WORD * sizeof(uint32));
    sal_memset(mask_entry, 0, MAX_ENTRY_WORD * sizeof(uint32));
    tbl_name = (char*)p_para->tbl_str;

    if (drv_usw_get_tbl_id_by_string(lchip, &tbl_id, tbl_name)
        || (0 == DRV_TABLE_MAX_INDEX(lchip, tbl_id) && SYS_DIAG_TBL_SKIP_CHK(tbl_id)))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% Not found %s\n", tbl_name);
        ret = CTC_E_NOT_EXIST;
        goto clean;
    }
    index_temp = (DsFwd_t == tbl_id) ? (DRV_TABLE_MAX_INDEX(lchip, tbl_id)*2) : DRV_TABLE_MAX_INDEX(lchip, tbl_id);
    if(p_para->index >= index_temp  && SYS_DIAG_TBL_SKIP_CHK(tbl_id))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% the index %u exceed max index %u\n", p_para->index,(uint32)DRV_TABLE_MAX_INDEX(lchip, tbl_id));
        ret = CTC_E_INVALID_PARAM;
        goto clean;
    }
    tbl_id_tmp = tbl_id;
    SYS_DIAG_TBL_ID_CONVERT(tbl_id, tbl_id);

    tbl_ptr = TABLE_INFO_PTR(lchip, tbl_id);
    loop = (p_para->entry_num && (tbl_ptr->field_num > p_para->entry_num))? p_para->entry_num: tbl_ptr->field_num;
    for (i = 0; (field_cnt < loop) && (i < tbl_ptr->field_num); i++)
    {
        if (!p_para->entry_num || !p_para->info)
        {
            fld_ptr = &(tbl_ptr->ptr_fields[i]);
            if (fld_ptr->bits)
            {
                field_cnt++;
            }
            continue;
        }
        index = p_para->index;
        if(sal_strlen(p_para->info[field_cnt].str) == 0)
        {
            fld_ptr = &(tbl_ptr->ptr_fields[i]);
            if (fld_ptr->bits == 0)
            {
                continue;
            }
            sal_strncpy(fld_name, FIELD_NAME(lchip, tbl_id, i), CTC_DIAG_TBL_NAME_SIZE-1);
            sal_strncpy(p_para->info[field_cnt].str, FIELD_NAME(lchip, tbl_id, i), CTC_DIAG_TBL_NAME_SIZE-1);
        }
        else
        {
            sal_strncpy(fld_name, p_para->info[field_cnt].str, CTC_DIAG_TBL_NAME_SIZE-1);
        }
        CTC_ERROR_GOTO(drv_usw_get_field_id_by_string(lchip, tbl_id, &field_id, fld_name),ret,clean);
        fld_ptr = TABLE_FIELD_INFO_PTR(lchip, tbl_id) + field_id;
        p_para->info[field_cnt].field_len = fld_ptr->bits;
        /* only support CTC_DIAG_MAX_FIELD_LEN*32 field*/
        if(fld_ptr->bits > CTC_DIAG_MAX_FIELD_LEN * 32)
        {
            continue;
        }
        if ((DRV_TABLE_TYPE_TCAM == drv_usw_get_table_type(lchip, tbl_id))
        || (DRV_TABLE_TYPE_LPM_TCAM_IP == drv_usw_get_table_type(lchip, tbl_id))
        || (DRV_TABLE_TYPE_LPM_TCAM_NAT == drv_usw_get_table_type(lchip, tbl_id))
        || (DRV_TABLE_TYPE_STATIC_TCAM_KEY == drv_usw_get_table_type(lchip, tbl_id)))
        {
            entry.data_entry = data_entry;
            entry.mask_entry = mask_entry;
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            if((DRV_TABLE_TYPE_LPM_TCAM_IP == drv_usw_get_table_type(lchip, tbl_id)) ||
                (DRV_TABLE_TYPE_LPM_TCAM_NAT == drv_usw_get_table_type(lchip, tbl_id)))
            {
                _sys_usw_diag_tcam_io(lchip, index, cmd, &entry);
            }
            else
            {
                DRV_IOCTL(lchip, index, cmd, &entry);
            }
            drv_get_field(lchip, tbl_id, field_id, data_entry, p_para->info[field_cnt].value);
            drv_get_field(lchip, tbl_id, field_id, mask_entry, p_para->info[field_cnt].mask);
        }
        else
        {
            if (_sys_usw_diag_table_is_hash_key(lchip, tbl_id))
            {
                ret =  _sys_usw_diag_table_acc_read(lchip, tbl_id, index, (void*)(data_entry));/*merge table and cam*/
            }
            else
            {

                if (DsFwdHalf_t == tbl_id_tmp)
                {
                    tbl_id_tmp = DsFwd_t;
                }

                if ((DsIpfixSessionRecord_t == tbl_id_tmp) || (DsFwd_t == tbl_id_tmp) )
                {
                    index_temp = index / 2;
                }
                else
                {
                    index_temp = index;
                }

                if (DsL2Edit3WOuter_t == tbl_id_tmp)
                {
                    tbl_id_tmp = DsL2Edit6WOuter_t;
                    index_temp = index/2;
                }

                if (DsL3Edit3W3rd_t == tbl_id_tmp)
                {
                    tbl_id_tmp = DsL3Edit6W3rd_t;
                    index_temp = index/2;
                }

                cmd = DRV_IOR(tbl_id_tmp, DRV_ENTRY_FLAG);
                ret = DRV_IOCTL(lchip, index_temp, cmd, data_entry);
            }
            if (CTC_E_NONE == ret)
            {
                if (DsFwd_t == tbl_id)
                {
                    drv_get_field(lchip, DsFwd_t, DsFwd_isHalf_f, data_entry, (uint32*)&is_half);
                }
                if ((DsFwdHalf_t == tbl_id) || ((DsFwd_t == tbl_id)&&is_half))
                {
                    DsFwdHalf_m dsfwd_half;

                    if (index % 2 == 0)
                    {
                        drv_get_field(lchip, DsFwdDualHalf_t, DsFwdDualHalf_g_0_dsFwdHalf_f,   data_entry,   (uint32*)&dsfwd_half);
                    }
                    else
                    {
                        drv_get_field(lchip, DsFwdDualHalf_t, DsFwdDualHalf_g_1_dsFwdHalf_f,   data_entry,   (uint32*)&dsfwd_half);
                    }

                    sal_memcpy(data_entry, &dsfwd_half, sizeof(dsfwd_half));
                }
                drv_get_field(lchip, tbl_id, field_id, data_entry, p_para->info[field_cnt].value);
            }
        }
        field_cnt++;
    }
    p_para->entry_num = field_cnt;
    if (ret < 0)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Read index %d failed %d\n", index, ret);
    }
clean:
    mem_free(data_entry);
    mem_free(mask_entry);

    return ret;
}

STATIC int32
_sys_usw_diag_write_tbl(uint8 lchip, ctc_diag_tbl_t *p_para)
{
    char* reg_name = NULL;
    int32 index = 0;
    uint32 index_temp = 0;
    uint32 reg_tbl_id = 0;
    uint32 input_tbl_id = 0;
    uint32 tmp_reg_tbl_id = 0;
    uint32 field_value = 0;
    uint32 entry_num = 0;
    uint32* mask = NULL;
    uint32* value = NULL;
    uint32 cmd = 0;
    int32 ret = 0;
    fld_id_t fld_id = 0;
    tbl_entry_t field_entry;
    DsL2EditEth3W_m ds_l2_edit_eth3_w;
    DsL2Edit6WOuter_m ds_l2_edit6_w_outer;
    DsL3Edit3W3rd_m ds_mpls_3w;
    DsL3Edit6W3rd_m ds_mpls_6w;
    DsFwdHalf_m dsfwd_half;
    uint32 is_half = 0;
    uint32 loop = 0;

    CTC_PTR_VALID_CHECK(p_para->info);

    mask = (uint32*)mem_malloc(MEM_DIAG_MODULE,MAX_ENTRY_WORD * sizeof(uint32));
    value = (uint32*)mem_malloc(MEM_DIAG_MODULE,MAX_ENTRY_WORD * sizeof(uint32));

    if (!mask || !value)
    {
        ret = CTC_E_NO_MEMORY;
        goto WRITE_TABLE_ERROR;
    }

    sal_memset(mask, 0, MAX_ENTRY_WORD * sizeof(uint32));
    sal_memset(value, 0, MAX_ENTRY_WORD * sizeof(uint32));

    index_temp = p_para->index;
    reg_name = (char*)p_para->tbl_str;

    if (DRV_E_NONE != drv_usw_get_tbl_id_by_string(lchip, &reg_tbl_id, reg_name)
        || (0 == DRV_TABLE_MAX_INDEX(lchip, reg_tbl_id) && SYS_DIAG_TBL_SKIP_CHK(reg_tbl_id)))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% Not found %s\n", reg_name);
        ret = CTC_E_NOT_EXIST;
        goto WRITE_TABLE_ERROR;
    }

    entry_num  = (DsFwd_t == reg_tbl_id) ? (DRV_TABLE_MAX_INDEX(lchip, reg_tbl_id)*2) : DRV_TABLE_MAX_INDEX(lchip, reg_tbl_id);
    if(p_para->index >= entry_num && SYS_DIAG_TBL_SKIP_CHK(reg_tbl_id))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% the index %u exceed max index %u\n", p_para->index,(uint32)DRV_TABLE_MAX_INDEX(lchip, reg_tbl_id));
        ret = CTC_E_INVALID_PARAM;
        goto WRITE_TABLE_ERROR;
    }

    if ((reg_tbl_id) <= 0 || (reg_tbl_id) >= MaxTblId_t)
    {
        ret = CTC_E_NOT_EXIST;
        goto WRITE_TABLE_ERROR;
    }

    SYS_DIAG_TBL_ID_CONVERT(reg_tbl_id, tmp_reg_tbl_id);
    if ((DsIpfixSessionRecord_t == reg_tbl_id))
    {
        index = index_temp / 2;
    }
    else if ((DsFwd_t == reg_tbl_id) || (DsFwdHalf_t == reg_tbl_id))
    {
        index = index_temp / 2;
        reg_tbl_id = DsFwd_t;
    }
    else if (DsL2Edit3WOuter_t == reg_tbl_id)
    {
        reg_tbl_id = DsL2Edit6WOuter_t;
        index = index_temp / 2;
        input_tbl_id = DsL2Edit3WOuter_t;
    }
    else if (DsL3Edit3W3rd_t == reg_tbl_id)
    {
        index = index_temp / 2;
        reg_tbl_id = DsL3Edit6W3rd_t;
        input_tbl_id = DsL3Edit3W3rd_t;
    }
    else if (DsApsBridgeRtl_t == reg_tbl_id || DsApsBridge_t == reg_tbl_id)
    {
        /* write field or entry handle by function drv_ioctl_aps_mask_api */
        CTC_ERROR_GOTO(drv_usw_get_field_id_by_string(lchip, tmp_reg_tbl_id, &fld_id, p_para->info[0].str), ret, WRITE_TABLE_ERROR);
        cmd = DRV_IOW(DsApsBridgeMask_t, fld_id);
        ret = DRV_IOCTL(lchip, 0, cmd, value);
        index = index_temp;
    }
    else
    {
        index = index_temp;
    }

    if (DRV_TBL_TYPE_DYN_LPM == TABLE_IOCTL_TYPE(lchip, reg_tbl_id))
    {
        for(loop = 0; loop < p_para->entry_num; loop ++)
        {
            if (CTC_E_NONE != drv_usw_get_field_id_by_string(lchip, tmp_reg_tbl_id, &fld_id, p_para->info[loop].str))
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% Not found %s\n", p_para->info[loop].str);
                continue;
            }

            drv_set_field(lchip, reg_tbl_id, fld_id, value, p_para->info[loop].value);
            sal_memset(p_para->info[loop].mask, 0xff, sizeof(p_para->info[loop].mask));
            drv_set_field(lchip, reg_tbl_id, fld_id, mask, p_para->info[loop].mask);
            field_entry.data_entry = value;
            field_entry.mask_entry = mask;
            cmd = DRV_IOW(reg_tbl_id, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, index_temp, cmd, &field_entry);
            if (ret < 0)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% Write %s index %d failed %d\n",  "tbl-reg", index_temp, ret);
                break;
            }
        }
        goto WRITE_TABLE_ERROR;
    }

    /*1.read firstly*/
    DRV_TBL_EMPTY_CHECK(lchip, reg_tbl_id);

    cmd = DRV_IOR(reg_tbl_id, DRV_ENTRY_FLAG);
    if (DRV_TABLE_TYPE_TCAM == drv_usw_get_table_type(lchip, reg_tbl_id)
        || DRV_TABLE_TYPE_LPM_TCAM_IP == drv_usw_get_table_type(lchip, reg_tbl_id)
        || DRV_TABLE_TYPE_STATIC_TCAM_KEY == drv_usw_get_table_type(lchip, reg_tbl_id)
        || DRV_TABLE_TYPE_LPM_TCAM_NAT == drv_usw_get_table_type(lchip, reg_tbl_id))
    {
        field_entry.data_entry = value;
        field_entry.mask_entry = mask;
        if((DRV_TABLE_TYPE_LPM_TCAM_IP == drv_usw_get_table_type(lchip, reg_tbl_id)) ||
                (DRV_TABLE_TYPE_LPM_TCAM_NAT == drv_usw_get_table_type(lchip, reg_tbl_id)))
        {
            ret = _sys_usw_diag_tcam_io(lchip, index, cmd, &field_entry);
        }
        else
        {
            ret = DRV_IOCTL(lchip, index, cmd, &field_entry);
        }
    }
    else
    {
        if (_sys_usw_diag_table_is_hash_key(lchip, reg_tbl_id))
        {
            _sys_usw_diag_table_acc_read(lchip, reg_tbl_id, index_temp, (void*)(value));
        }
        else
        {
            ret = DRV_IOCTL(lchip, index, cmd, value);
            if (DsFwd_t == reg_tbl_id)
            {
                drv_get_field(lchip, DsFwd_t, DsFwd_isHalf_f, value, (uint32*)&is_half);
            }
            if (DsL2Edit3WOuter_t == input_tbl_id)
            {
                sal_memset(&ds_l2_edit_eth3_w, 0, sizeof(ds_l2_edit_eth3_w));
                sal_memset(&ds_l2_edit6_w_outer, 0, sizeof(ds_l2_edit6_w_outer));
                sal_memcpy((uint8*)&ds_l2_edit6_w_outer, (uint8*)value, DRV_TABLE_ENTRY_SIZE(lchip, DsL2Edit6WOuter_t));
                if ((index_temp&0x01))
                {
                    sal_memcpy((uint8*)&ds_l2_edit_eth3_w, (uint8*)&ds_l2_edit6_w_outer + DRV_TABLE_ENTRY_SIZE(lchip, DsL2EditEth3W_t), DRV_TABLE_ENTRY_SIZE(lchip, DsL2EditEth3W_t));
                }
                else
                {
                    sal_memcpy((uint8*)&ds_l2_edit_eth3_w, (uint8*)&ds_l2_edit6_w_outer, DRV_TABLE_ENTRY_SIZE(lchip, DsL2EditEth3W_t));
                }
            }
            else if (DsL3Edit3W3rd_t == input_tbl_id)
            {
                sal_memset(&ds_mpls_3w, 0, sizeof(ds_mpls_3w));
                sal_memset(&ds_mpls_6w, 0, sizeof(ds_mpls_6w));
                sal_memcpy((uint8*)&ds_mpls_6w, (uint8*)value, DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit6W3rd_t));
                if ((index_temp&0x01))
                {
                    sal_memcpy((uint8*)&ds_mpls_3w, (uint8*)&ds_mpls_6w + DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit3W3rd_t), DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit3W3rd_t));
                }
                else
                {
                    sal_memcpy((uint8*)&ds_mpls_3w, (uint8*)&ds_mpls_6w, DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit3W3rd_t));
                }
            }
            else if ((DsFwd_t == reg_tbl_id) && is_half)
            {
                if (index_temp % 2 == 0)
                {
                    drv_get_field(lchip, DsFwdDualHalf_t, DsFwdDualHalf_g_0_dsFwdHalf_f, value, (uint32*)&dsfwd_half);
                }
                else
                {
                    drv_get_field(lchip, DsFwdDualHalf_t, DsFwdDualHalf_g_1_dsFwdHalf_f, value, (uint32*)&dsfwd_half);
                }
            }
        }
    }
    /*2.write secondly*/
    for(loop = 0; loop < p_para->entry_num; loop ++)
    {
        if (CTC_E_NONE != drv_usw_get_field_id_by_string(lchip, tmp_reg_tbl_id, &fld_id, p_para->info[loop].str))
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% Not found %s\n", p_para->info[loop].str);
            continue;
        }

        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"Write %s %d %s\n", reg_name, index_temp, p_para->info[loop].str);
        cmd = DRV_IOW(reg_tbl_id, DRV_ENTRY_FLAG);
        if ((DRV_TABLE_TYPE_TCAM == drv_usw_get_table_type(lchip, reg_tbl_id)
            || DRV_TABLE_TYPE_LPM_TCAM_IP == drv_usw_get_table_type(lchip, reg_tbl_id)
            || DRV_TABLE_TYPE_LPM_TCAM_NAT == drv_usw_get_table_type(lchip, reg_tbl_id)
            || DRV_TABLE_TYPE_STATIC_TCAM_KEY == drv_usw_get_table_type(lchip, reg_tbl_id)))
        {
            drv_set_field(lchip, reg_tbl_id, fld_id, field_entry.data_entry, p_para->info[loop].value);
            drv_set_field(lchip, reg_tbl_id, fld_id, field_entry.mask_entry, p_para->info[loop].mask);
            if((DRV_TABLE_TYPE_LPM_TCAM_IP == drv_usw_get_table_type(lchip, reg_tbl_id)) ||
                    (DRV_TABLE_TYPE_LPM_TCAM_NAT == drv_usw_get_table_type(lchip, reg_tbl_id)))
            {
                ret = _sys_usw_diag_tcam_io(lchip, index, cmd, &field_entry);
            }
            else
            {
                ret = DRV_IOCTL(lchip, index, cmd, &field_entry);
            }
        }
        else
        {
            if (DsL2Edit3WOuter_t == input_tbl_id)
            {
                SYS_DIAG_TBL_ID_CONVERT(input_tbl_id, input_tbl_id);
                drv_set_field(lchip, input_tbl_id, fld_id, (uint8*)&ds_l2_edit_eth3_w, p_para->info[loop].value);
                if ((index_temp&0x01))
                {
                    sal_memcpy((uint8*)&ds_l2_edit6_w_outer + DRV_TABLE_ENTRY_SIZE(lchip, DsL2EditEth3W_t), (uint8*)&ds_l2_edit_eth3_w, DRV_TABLE_ENTRY_SIZE(lchip, DsL2EditEth3W_t));
                }
                else
                {
                    sal_memcpy((uint8*)&ds_l2_edit6_w_outer, (uint8*)&ds_l2_edit_eth3_w, DRV_TABLE_ENTRY_SIZE(lchip, DsL2EditEth3W_t));
                }
                sal_memcpy((uint8*)value, (uint8*)&ds_l2_edit6_w_outer, DRV_TABLE_ENTRY_SIZE(lchip, DsL2Edit6WOuter_t));
            }
            else if (DsL3Edit3W3rd_t == input_tbl_id)
            {
                SYS_DIAG_TBL_ID_CONVERT(input_tbl_id, input_tbl_id);
                drv_set_field(lchip, input_tbl_id, fld_id, (uint8*)&ds_mpls_3w, p_para->info[loop].value);
                if ((index_temp&0x01))
                {
                    sal_memcpy((uint8*)&ds_mpls_6w + DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit3W3rd_t), (uint8*)&ds_mpls_3w, DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit3W3rd_t));
                }
                else
                {
                    sal_memcpy((uint8*)&ds_mpls_6w, (uint8*)&ds_mpls_3w, DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit3W3rd_t));
                }
                sal_memcpy((uint8*)value, (uint8*)&ds_mpls_6w, DRV_TABLE_ENTRY_SIZE(lchip, DsL3Edit6W3rd_t));
            }
            else if (DsFwd_t == reg_tbl_id && is_half)
            {
                drv_set_field(lchip, tmp_reg_tbl_id, fld_id, (uint8*)&dsfwd_half, p_para->info[loop].value);
                if (index_temp % 2 == 0)
                {
                    drv_set_field(lchip, DsFwdDualHalf_t, DsFwdDualHalf_g_0_dsFwdHalf_f, (uint8*)value, (uint32*)&dsfwd_half);
                }
                else
                {
                    drv_set_field(lchip, DsFwdDualHalf_t, DsFwdDualHalf_g_1_dsFwdHalf_f, (uint8*)value, (uint32*)&dsfwd_half);
                }
            }
            else
            {
                drv_set_field(lchip, reg_tbl_id, fld_id, value, p_para->info[loop].value);
            }
            if (_sys_usw_diag_table_is_hash_key(lchip, reg_tbl_id))
            {
                _sys_usw_diag_table_acc_write(lchip, reg_tbl_id, index_temp, (void*)(value));
            }
            else
            {
                if (((DsEthMep_t == reg_tbl_id) || (DsEthRmep_t == reg_tbl_id) || (DsBfdMep_t == reg_tbl_id) || (DsBfdRmep_t == reg_tbl_id)))
                {
                    sal_memset(mask, 0xFF, MAX_ENTRY_WORD * sizeof(uint32));
                    field_value = 0;
                    drv_set_field(lchip, reg_tbl_id, fld_id, mask, &field_value);
                    field_entry.data_entry = value;
                    field_entry.mask_entry = mask;
                    ret = DRV_IOCTL(lchip, index, cmd, &field_entry);
                }
                else
                {
                    ret = DRV_IOCTL(lchip, index, cmd, value);
                }
            }
        }
    }
    if (ret < 0)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"%% Write %s index %d failed %d\n",  "tbl-reg", index_temp, ret);
    }

WRITE_TABLE_ERROR:
    if (mask)
    {
        mem_free(mask);
    }
    if (value)
    {
        mem_free(value);
    }

    return ret;
}

STATIC int32
_sys_usw_diag_list_tbl(uint8 lchip, ctc_diag_tbl_t *p_para)
{
    uint16 fld_idx = 0;
    fields_t* fld_ptr = NULL;
    uint32  *ids = NULL;
    char*    upper_name = NULL;
    char*    upper_name1 = NULL;
    tables_info_t* tbl_ptr = NULL;
    uint32  i = 0;
    uint32  id_index = 0;
    char* p_char = NULL;
    int32 ret = CTC_E_NONE;
    uint32 loop = 0;
    uint32 index_num = 0;

    ids = (uint32 *)mem_malloc(MEM_DIAG_MODULE,SYS_DIAG_LIST_MAX_NUM * sizeof(uint32));
    if(ids == NULL)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% No memory\n");
        return CTC_E_NO_MEMORY;
    }
    upper_name = (char*)mem_malloc(MEM_DIAG_MODULE,CTC_DIAG_TBL_NAME_SIZE * sizeof(char));
    if(upper_name == NULL)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% No memory\n");
        ret = CTC_E_NO_MEMORY;
        goto clean;
    }
    upper_name1 = (char*)mem_malloc(MEM_DIAG_MODULE,CTC_DIAG_TBL_NAME_SIZE * sizeof(char));
    if(upper_name1 == NULL)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% No memory\n");
        ret = CTC_E_NO_MEMORY;
        goto clean;
    }

    sal_memset(ids, 0, SYS_DIAG_LIST_MAX_NUM * sizeof(uint32));
    sal_memset(upper_name, 0, CTC_DIAG_TBL_NAME_SIZE * sizeof(char));
    sal_memset(upper_name1, 0, CTC_DIAG_TBL_NAME_SIZE * sizeof(char));

    sal_strncpy((char*)upper_name, (char*)p_para->tbl_str, CTC_DIAG_TBL_NAME_SIZE-1);
    _sys_usw_diag_table_str_to_upper(upper_name);

    for (i = 0; i < MaxTblId_t; i++)
    {
        drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, i, 0, (char*)upper_name1);
        _sys_usw_diag_table_str_to_upper(upper_name1);

        p_char = (char*)sal_strstr((char*)upper_name1, (char*)upper_name);
        if (p_char)
        {
            if (0 == DRV_TABLE_MAX_INDEX(lchip, i))
            {
                continue;
            }

            if (sal_strlen((char*)upper_name1) == sal_strlen((char*)upper_name))
            {
                uint32 e_cnt = 0;
                /* list full matched */
                tbl_ptr = TABLE_INFO_PTR(lchip, i);
                index_num = DRV_TABLE_MAX_INDEX(lchip, i);
                index_num = ((i == DsFwd_t) || (i == DsFwdHalf_t))? index_num*2: index_num;
                for (fld_idx = 0; fld_idx < tbl_ptr->field_num; fld_idx++)
                {
                    fld_ptr = &(tbl_ptr->ptr_fields[fld_idx]);
                    if (fld_ptr->bits == 0)
                    {
                        continue;
                    }
                    if (e_cnt < p_para->entry_num)
                    {
                        sal_strncpy(p_para->info[e_cnt].str, FIELD_NAME(lchip, i, fld_idx), CTC_DIAG_TBL_NAME_SIZE-1);
                    }
                    e_cnt++;
                }
                p_para->entry_num = e_cnt;
                p_para->index = index_num;
                goto clean;
            }
            else
            {
                ids[id_index] = i;
                id_index++;
            }

            if (id_index >= SYS_DIAG_LIST_MAX_NUM)
            {
                break;
            }
        }
    }

    if (id_index == 0)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "%% Not found %s \n", p_para->tbl_str);
        ret = CTC_E_NOT_EXIST;
        goto clean;
    }
    loop = (p_para->entry_num > id_index) ? id_index : p_para->entry_num;
    for (i = 0; i < loop; i++)
    {
        /* list matched */
        drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, ids[i], 0, p_para->info[i].str);
    }
    p_para->entry_num = id_index;

clean:
    if(NULL != ids)
    {
        mem_free(ids);
    }
    if(NULL != upper_name)
    {
        mem_free(upper_name);
    }
    if(NULL != upper_name1)
    {
        mem_free(upper_name1);
    }

    return ret;
}
STATIC int32
_sys_usw_diag_tbl_control(uint8 lchip, ctc_diag_tbl_t *p_para)
{
    char *p_tcam_type_str[DRV_FTM_TCAM_TYPE_MAX] = {
                                                    "IpeAcl0", "IpeAcl1", "IpeAcl2", "IpeAcl3", "IpeAcl4", "IpeAcl5", "IpeAcl6", "IpeAcl7", "IpeAcl8", "IpeAcl9",
                                                    "IpeAcl10", "IpeAcl11", "IpeAcl12", "IpeAcl13", "IpeAcl14", "IpeAcl15", "IpeAcl16", "IpeAcl17", "IpeAcl18",
                                                    "IpeAcl19", "IpeAcl20", "IpeAcl21", "IpeAcl22", "IpeAcl23", "EpeAcl0", "EpeAcl1", "EpeAcl2", "EpeAcl3", "EpeAcl4", 
                                                    "EpeAcl5", "EpeAcl6", "EpeAcl7", "EpeAcl8", "EpeAcl9", "EpeAcl10", "EpeAcl11", "IpeSCL0", "IpeSCL1", "IpeSCL2",
                                                    "IpeSCL3", "EpeSCL0", "EpeSCL1", "LPM0All", "LPM0DaPrivate", "LPM0SaPrivate", "LPM0DaPublic", "LPM0SaPublic",
                                                    "LPM1All", "StaticTcam", "IPv4UC", "IPv4NAT", "IPv6UC", "IPv6UCHalf"
                      };
    char *p_sram_type_str[DRV_FTM_SRAM_TBL_MAX + 1] = {
                                                   "MacHashKey", "FibHost0HashKey", "FibHost1HashKey", "FlowHashKey", "IpfixHashKey0", "IpfixHashKey1",
                                                    "IpeScl0HashKey", "IpeScl1HashKey", "XcOamHashKey", "EpeScl0HashKey", "EpeScl1HashKey", "LpmLookupKey0",
                                                    "LpmLookupKey1", "LpmLookupKey2", "LpmLookupKey3", "DsMacAd", "DsIpAd", "DsFlowAd", "IpfixHashAd",
                                                    "IpfixHashAd1", "DsSclAd", "DsScl1Ad", "DsNexthop", "DsFwd", "DsMet", "DsEdit", "DsOamAps", "DsOamLm",
                                                    "DsOamProtocolLm", "DsOamMep", "DsOamMa", "DsOamMaName", "MplsHashKey", "MplsHashAd", "XgponGemPort",
                                                    "DsOamRmepKey", "DsOamHashKey", "AntFlow", "AntFlow2", "QueueHashKey", "DsNextHopIdMap", "DsFwd1",
                                                    "DsEdit1", "DsXEdit", "DsMetExt", "DsXKey1", "DsXKey2", "DsXSecRx", "DsXSecTx","Invalid"
                      };
    uint16 index = 0;

    switch (p_para->type)
    {
        case CTC_DIAG_TBL_OP_LIST:
            CTC_ERROR_RETURN(_sys_usw_diag_list_tbl(lchip, p_para));
            break;
        case CTC_DIAG_TBL_OP_READ:
            CTC_ERROR_RETURN(_sys_usw_diag_read_tbl(lchip, p_para));
            break;
        case CTC_DIAG_TBL_OP_WRITE:
            CTC_ERROR_RETURN(_sys_usw_diag_write_tbl(lchip, p_para));
            break;
        case CTC_DIAG_TBL_OP_ID2STR:
            CTC_ERROR_RETURN(drv_usw_get_tbl_string_by_id(lchip, p_para->tbl_id, p_para->tbl_str))
            break;
        case CTC_DIAG_TBL_OP_MEM2STR:
            CTC_MAX_VALUE_CHECK(p_para->tbl_id, (DRV_FTM_MAX_ID - 1));
            sal_strncpy(p_para->tbl_str, p_sram_type_str[DRV_FTM_SRAM_TBL_MAX], (CTC_DIAG_TBL_NAME_SIZE - 1)); /* default Invalid */
            index = drv_usw_ftm_memid_2_table(lchip, p_para->tbl_id);
            if (p_para->tbl_id<=DRV_FTM_EDRAM_MAX && index <DRV_FTM_SRAM_TBL_MAX)
            {
                sal_strncpy(p_para->tbl_str, p_sram_type_str[index], (CTC_DIAG_TBL_NAME_SIZE - 1));
            }
            else if (index <DRV_FTM_TCAM_TYPE_MAX)
            {
                sal_strncpy(p_para->tbl_str, p_tcam_type_str[index], (CTC_DIAG_TBL_NAME_SIZE - 1));
            }
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}
int32
_sys_usw_diag_get_ecmp_dest_gport(uint8 lchip, uint16 nh_id, uint32* p_gport, uint16* p_count)
{
    uint16 loop = 0;
    uint16 count = 0;
    sys_nh_info_dsnh_t nhinfo = {0};
    sys_nh_info_dsnh_t nhinfo_tmp = {0};
    int32 ret = CTC_E_NONE;
    
    *p_count = 0;
    nhinfo.nh_array =   mem_malloc(MEM_DIAG_MODULE, CTC_MAX_ECPN*sizeof(uint32)); 
    if(!nhinfo.nh_array)
    {
      return CTC_E_NO_MEMORY;
    } 
    CTC_ERROR_GOTO(sys_usw_nh_get_nhinfo(lchip, nh_id, &nhinfo, 0),ret,error_proc);
    if (nhinfo.ecmp_valid == 0)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Ecmp group id not exist \n");
        return CTC_E_NOT_EXIST;
    }
    count = nhinfo.valid_cnt;
    for (loop = 0; loop < count; loop ++)
    {
        CTC_ERROR_GOTO(sys_usw_nh_get_nhinfo(lchip, nhinfo.nh_array[loop], &nhinfo_tmp, 0),ret,error_proc);
        p_gport[loop] = nhinfo_tmp.gport;
    }
    *p_count = count;
 error_proc:     
    mem_free( nhinfo.nh_array );
    return ret;
}
STATIC int32
_sys_usw_diag_set_lb_distribution(uint8 lchip, ctc_diag_lb_dist_t* p_para)
{
    uint16 port_cnt = 0;
    uint32* p_gport = NULL;
    int32 ret = CTC_E_NONE;
    uint32 *gport = NULL;
    uint16 loop = 0;
    uint16 loop1 = 0;
    uint16 count = 0;
    uint8 gchip = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sys_usw_diag_lb_dist_t* p_lb_info = NULL;
    sys_usw_diag_lb_dist_t lb_info = {0};
    ctc_mac_stats_t mac_stats;
    uint32 channel_id = 0;
    ctc_linkagg_group_t linkagg_grp = {0};

    lb_info.group_id =  p_para->group_id;
    lb_info.flag = p_para->flag;
    p_lb_info = _sys_usw_diag_dist_hash_lkup(lchip, lb_info.group_id, lb_info.flag);
    if (NULL != p_lb_info)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry already exist \n");
        return CTC_E_EXIST;
    }
    p_lb_info = mem_malloc(MEM_DIAG_MODULE, sizeof(sys_usw_diag_lb_dist_t));
    if (NULL == p_lb_info)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No Memory! \n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_lb_info,0,sizeof(sys_usw_diag_lb_dist_t));

    gport = (uint32*)mem_malloc(MEM_DIAG_MODULE, (sizeof(uint32)*MCHIP_CAP(SYS_CAP_PHY_PORT_NUM_PER_SLICE)));
    if (NULL == gport)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No Memory! \n");
        ret = CTC_E_NO_MEMORY;
        goto error_proc;
    }

    if(CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_LINKAGG))
    {
        linkagg_grp.tid = p_para->group_id;
        CTC_ERROR_GOTO(sys_usw_linkagg_get_group_info(lchip, &linkagg_grp),ret,error_proc);
        if((CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_DYNAMIC) && linkagg_grp.linkagg_mode != CTC_LINKAGG_MODE_DLB) ||
           (!CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_DYNAMIC) && linkagg_grp.linkagg_mode != CTC_LINKAGG_MODE_STATIC))
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " The linkagg mode is not right! \n");
            ret = CTC_E_INVALID_PARAM;
            goto error_proc;
        }
        p_gport = (uint32*)mem_malloc(MEM_DIAG_MODULE, (sizeof(uint32)*linkagg_grp.member_num));
        if (NULL == p_gport)
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No Memory! \n");
            ret = CTC_E_NO_MEMORY;
            goto error_proc;
        }
        sal_memset(p_gport,0,(sizeof(uint32)*linkagg_grp.member_num));
        CTC_ERROR_GOTO(sys_usw_linkagg_get_ports(lchip, p_para->group_id, p_gport, &port_cnt),ret,error_proc);
        /* clear the same gport and remote gport*/
        for(loop = 0; loop < port_cnt; loop ++)
        {
            if(p_gport[loop] != 0xffffffff)
            {
                if ((0x1F == SYS_MAP_CTC_GPORT_TO_GCHIP(p_gport[loop])) || (SYS_MAP_CTC_GPORT_TO_GCHIP(p_gport[loop]) > MCHIP_CAP(SYS_CAP_GCHIP_CHIP_ID)))
                {           
                    ret = CTC_E_INVALID_CHIP_ID;
                    goto error_proc;
                }
                if (FALSE == sys_usw_chip_is_local(lchip, gchip))
                {
                    p_gport[loop] = 0xffffffff;
                }
            }
            for(loop1 = loop+1; loop1 < port_cnt; loop1 ++)
            {
                if(p_gport[loop1] == p_gport[loop])
                {
                    p_gport[loop1] = 0xffffffff;
                }
            }
        }
        for(loop = 0; loop < port_cnt; loop ++)
        {
            if(p_gport[loop] != 0xffffffff)
            {
                if(count == MCHIP_CAP(SYS_CAP_PHY_PORT_NUM_PER_SLICE))
                {
                    ret = CTC_E_INVALID_PARAM;
                    goto error_proc;
                }
                gport[count] = p_gport[loop];
                count ++;
            }
        }
        mem_free(p_gport);
        p_gport = NULL;
        p_lb_info->info = mem_malloc(MEM_DIAG_MODULE, sizeof(ctc_diag_lb_info_t) * count);
        if (NULL == p_lb_info->info)
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No Memory! \n");
            ret = CTC_E_NO_MEMORY;
            goto error_proc;
        }
        sal_memset(p_lb_info->info,0,sizeof(ctc_diag_lb_info_t) * count);
        if(!CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_DYNAMIC))
        {
            for(loop = 0; loop < count; loop ++)
            {
                p_lb_info->info[loop].gport = gport[loop];
                sal_memset(&mac_stats, 0, sizeof(ctc_mac_stats_t));
                mac_stats.stats_mode = CTC_STATS_MODE_DETAIL;
                CTC_ERROR_GOTO(sys_usw_mac_stats_get_tx_stats(lchip, gport[loop], &mac_stats),ret,error_proc);
                p_lb_info->info[loop].pkts = mac_stats.u.stats_detail.stats.tx_stats.good_ucast_pkts + mac_stats.u.stats_detail.stats.tx_stats.good_mcast_pkts +
                                        mac_stats.u.stats_detail.stats.tx_stats.good_bcast_pkts;
                p_lb_info->info[loop].bytes = mac_stats.u.stats_detail.stats.tx_stats.good_ucast_bytes + mac_stats.u.stats_detail.stats.tx_stats.good_mcast_bytes +
                                        mac_stats.u.stats_detail.stats.tx_stats.good_bcast_bytes;
            }
        }
        else
        {
            for(loop = 0; loop < count; loop ++)
            {
                dmps_port_info.gport = gport[loop];
                CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel_id), ret, error_proc);
                if (!SYS_IS_NETWORK_CHANNEL(channel_id))
                {
                    continue;
                }
                p_lb_info->info[loop].gport = gport[loop];
            }
        }
    }
    else
    {
        CTC_ERROR_GOTO(_sys_usw_diag_get_ecmp_dest_gport(lchip, p_para->group_id, gport, &count), ret, error_proc);

        p_lb_info->info = mem_malloc(MEM_DIAG_MODULE, sizeof(ctc_diag_lb_info_t) * count);
        if (NULL == p_lb_info->info)
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No Memory! \n");
            ret = CTC_E_NO_MEMORY;
            goto error_proc;
        }
        sal_memset(p_lb_info->info,0,sizeof(ctc_diag_lb_info_t) * count);

        if(CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_DYNAMIC))
        {
            for(loop = 0; loop < count; loop ++)
            {
                dmps_port_info.gport = gport[loop];
                CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel_id), ret, error_proc);
                gchip = SYS_MAP_CTC_GPORT_TO_GCHIP(gport[loop]);
                if (!sys_usw_chip_is_local(lchip, gchip))
                {
                    continue;
                }

                if (!SYS_IS_NETWORK_CHANNEL(channel_id))
                {
                    continue;
                }
                p_lb_info->info[loop].gport = gport[loop];
            }
        }
        else
        {
            ret = CTC_E_NOT_SUPPORT;
            goto error_proc;
        }
    }
    p_para->member_num = count;
    p_lb_info->member_num = count;
    p_lb_info->group_id = p_para->group_id;
    p_lb_info->flag = p_para->flag;
    CTC_ERROR_GOTO(_sys_usw_diag_dist_hash_add(lchip, p_lb_info),ret,error_proc);
    mem_free(gport);
    return ret;

error_proc:
    if(p_gport)
    {
        mem_free(p_gport);
    }
    if(gport)
    {
        mem_free(gport);
    }
    if(p_lb_info->info)
    {
        mem_free(p_lb_info->info);
    }
    if(p_lb_info)
    {
        mem_free(p_lb_info);
    }
    return ret;
}

STATIC int32
_sys_usw_diag_get_lb_distribution(uint8 lchip, ctc_diag_lb_dist_t* p_para)
{
    uint16 loop = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sys_usw_diag_lb_dist_t* p_lb_info = NULL;
    sys_usw_diag_lb_dist_t lb_info = {0};
    ctc_mac_stats_t mac_stats;
    uint32 channel_id = 0;
    uint8 lchip_base = drv_vchip_get_pp_base(lchip);
    uint32 pp_id = 0;
    uint32 dp_id = 0;
    uint16 member_num = 0;
    uint32 sub_chan = 0;
    uint8 gchip = 0;


    lb_info.group_id =  p_para->group_id;
    lb_info.flag = p_para->flag;
    p_lb_info = _sys_usw_diag_dist_hash_lkup(lchip, lb_info.group_id, lb_info.flag);
    if(p_lb_info == NULL)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    member_num = (p_para->member_num > p_lb_info->member_num) ? p_lb_info->member_num: p_para->member_num;
    
    if(CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_LINKAGG))
    {
        if(!CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_DYNAMIC))
        {
            for(loop = 0; loop < member_num; loop ++)
            {
                p_para->info[loop].gport = p_lb_info->info[loop].gport;
                sal_memset(&mac_stats, 0, sizeof(ctc_mac_stats_t));
                mac_stats.stats_mode = CTC_STATS_MODE_DETAIL;
                CTC_ERROR_RETURN(sys_usw_mac_stats_get_tx_stats(lchip, p_lb_info->info[loop].gport, &mac_stats));
                p_para->info[loop].pkts = mac_stats.u.stats_detail.stats.tx_stats.good_ucast_pkts + mac_stats.u.stats_detail.stats.tx_stats.good_mcast_pkts +
                                        mac_stats.u.stats_detail.stats.tx_stats.good_bcast_pkts - p_lb_info->info[loop].pkts;
                p_para->info[loop].bytes = mac_stats.u.stats_detail.stats.tx_stats.good_ucast_bytes + mac_stats.u.stats_detail.stats.tx_stats.good_mcast_bytes +
                                        mac_stats.u.stats_detail.stats.tx_stats.good_bcast_bytes - p_lb_info->info[loop].bytes;
            }
        }
        else
        {
          
            for(loop = 0; loop < member_num; loop ++)
            {
                dmps_port_info.gport = p_lb_info->info[loop].gport;
                CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel_id));
                gchip = SYS_MAP_CTC_GPORT_TO_GCHIP(p_lb_info->info[loop].gport);
                if (!sys_usw_chip_is_local(lchip, gchip))
                {
                    continue;
                }
                if (!SYS_IS_NETWORK_CHANNEL(channel_id))
                {
                    continue;
                }

                if(DRV_IS_AT(lchip))
                {
                    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan));
                    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &dp_id));
                    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &pp_id));
                    cmd = DRV_IOR(DsEpeHeaderEditChannelByteCounterCur_t, DsEpeHeaderEditChannelByteCounterCur_byteCount_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip_base+pp_id , ((sub_chan <<1 ) + dp_id), DRV_CMD_PP_EN(cmd), &value));
                }
                else
                {
                    cmd = DRV_IOR(((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? LagEngineChannelByteCounterCurS0_t : DsDlbChanCurrentLoad_t), ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? LagEngineChannelByteCounterCurS0_byteCount_f : DsDlbChanCurrentLoad_byteCount_f));
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel_id, cmd, &value));
                }
                p_para->info[loop].gport = p_lb_info->info[loop].gport;
                p_para->info[loop].bytes = value;
            }
        }
    }
    else
    {
        if(CTC_FLAG_ISSET(p_para->flag, CTC_DIAG_LB_DIST_IS_DYNAMIC))
        {
            for(loop = 0; loop < member_num; loop ++)
            {
                dmps_port_info.gport = p_lb_info->info[loop].gport;
                CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel_id));
                gchip = SYS_MAP_CTC_GPORT_TO_GCHIP(p_lb_info->info[loop].gport);
                if (!sys_usw_chip_is_local(lchip, gchip))
                {
                    continue;
                }
                if (!SYS_IS_NETWORK_CHANNEL(channel_id))
                {
                    continue;
                }
                if(DRV_IS_AT(lchip))
                {
                    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan));
                    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &dp_id));
                    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &pp_id));
                    cmd = DRV_IOR(DsEpeHeaderEditChannelByteCounterCur_t, DsEpeHeaderEditChannelByteCounterCur_byteCount_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip_base+pp_id , ((sub_chan <<1) + dp_id), DRV_CMD_PP_EN(cmd), &value));
                }
                else
                {
                    cmd = DRV_IOR(((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? LagEngineChannelByteCounterCurS0_t : DsDlbChanCurrentLoad_t), ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? LagEngineChannelByteCounterCurS0_byteCount_f : DsDlbChanCurrentLoad_byteCount_f));
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel_id, cmd, &value));
                }
                p_para->info[loop].gport = p_lb_info->info[loop].gport;
                p_para->info[loop].bytes = value;
            }
        }
    }
    p_para->member_num = p_lb_info->member_num;
    CTC_ERROR_RETURN(_sys_usw_diag_dist_hash_remove(lchip, p_lb_info));

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_diag_set_drop_pkt_cb(uint8 lchip, ctc_diag_drop_pkt_config_t* p_cfg)
{
    uint8 is_register = 0;
    ctc_pkt_rx_register_t rx_register;
    sal_memset(&rx_register, 0, sizeof(ctc_pkt_rx_register_t));
    rx_register.cb = sys_usw_diag_drop_pkt_sync;
    CTC_BMP_SET(rx_register.reason_bmp, CTC_PKT_CPU_REASON_DIAG_DISCARD_PKT);

    if (p_cfg->flags & CTC_DIAG_DROP_PKT_STORE_EN)
    {
        if (p_usw_diag_master[lchip]->drop_pkt_report_cb == NULL)
        {
            if (p_cfg->storage_en)
            {
                CTC_ERROR_RETURN(sys_usw_packet_rx_register(lchip, &rx_register));
                is_register = 1;
            }
            else if (!((p_cfg->flags & CTC_DIAG_DROP_PKT_REPORT_CALLBACK) && p_cfg->report_cb))
            {
                CTC_ERROR_RETURN(sys_usw_packet_rx_unregister(lchip, &rx_register));
            }
        }
    }

    if (p_cfg->flags & CTC_DIAG_DROP_PKT_REPORT_CALLBACK)
    {
        if (p_usw_diag_master[lchip]->drop_pkt_list == NULL)
        {
            if (p_cfg->report_cb && !is_register)
            {
                CTC_ERROR_RETURN(sys_usw_packet_rx_register(lchip, &rx_register));
            }
            else if (!((p_cfg->flags & CTC_DIAG_DROP_PKT_STORE_EN) && p_cfg->storage_en))
            {
                CTC_ERROR_RETURN(sys_usw_packet_rx_unregister(lchip, &rx_register));
            }
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_get_mem_usage(uint8 lchip, ctc_diag_mem_usage_t* p_para)
{
    sys_ftm_specs_info_t specs_info = {0};
    drv_ftm_info_detail_t p_ftm_info;
    uint32 entry_num = 0;
    uint32 entry_num1 = 0;
    uint32 cam_num = 0;
    uint32 used_num = 0;
    uint8 loop = 0;
    uint32 edit_name[][2] =
            {
                {DsFwd_t,SYS_API_NH_DSFWD},
                {DsMet_t,SYS_API_NH_NUM},
                {DsMetEntrySlim1X_t,SYS_API_NH_DSMET},
                {DsNextHop4W_t,SYS_API_NH_NEXTHOP_4W},
                {DsFwd1_t,SYS_API_NH_DSFWD1},
                {DsL2EditAddEth1X0_t,SYS_API_NH_L2EDIT_INNER},
                {DsL2EditEth3W_t,SYS_API_NH_L2EDIT},
                {0,SYS_API_NH_L3EDIT},
                {0,SYS_API_NH_L3EDIT_SPME},
                {0,SYS_API_NH_L2EDIT_OUTER_4W},
                {0,SYS_API_NH_L3EDIT_INNER},
            };
    if(DRV_FROM_TMM(lchip))
    {
        edit_name[6][0] = DsL2EditAddEth1X_t;
    }
    switch(p_para->type)
    {
        case CTC_DIAG_TYPE_SRAM_MAC:
            drv_usw_ftm_get_entry_num(lchip, DsFibHost0MacHashKey_t, &entry_num);
            cam_num = FLOW_HASH_CAM_NUM;
            sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_MAC,&specs_info);
            p_para->total_num = (entry_num+cam_num);
            p_para->used_num = specs_info.used_size;
            break;

        case CTC_DIAG_TYPE_SRAM_IP_HOST:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,CTC_DIAG_SUB_TYPE_IPV6);
            drv_usw_ftm_get_entry_num(lchip, DsFibHost0Ipv4HashKey_t, &entry_num);
            cam_num = FIB_HOST0_CAM_NUM;
            if(p_para->sub_type == 0)
            {
                specs_info.type = 0;
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_IPUC_HOST,&specs_info);
                used_num = specs_info.used_size+used_num;
                specs_info.type = 1;
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_IPUC_HOST,&specs_info);
                used_num = specs_info.used_size+used_num;
            }
            else
            {
                specs_info.type = p_para->sub_type - 1;
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_IPUC_HOST,&specs_info);
                used_num = specs_info.used_size+used_num;
            }
            p_para->total_num = (entry_num+cam_num);
            p_para->used_num = used_num;
            break;

        case CTC_DIAG_TYPE_SRAM_IP_LPM:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,CTC_DIAG_SUB_TYPE_IPV6);
            drv_usw_ftm_get_entry_num(lchip, DsNeoLpmIpv4Bit32Snake_t, &entry_num);
            drv_usw_ftm_get_entry_num(lchip, DsNeoLpmIpv4Bit32Snake1_t, &entry_num1);
            entry_num += entry_num1;
            entry_num = entry_num*6/4;
            if(p_para->sub_type == 0)
            {
                specs_info.type = 0;
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_IPUC_LPM,&specs_info);
                used_num = specs_info.used_size+used_num;
                specs_info.type = 1;
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_IPUC_LPM,&specs_info);
                used_num = specs_info.used_size+used_num;
            }
            else
            {
                specs_info.type = p_para->sub_type - 1;
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_IPUC_LPM,&specs_info);
                used_num = specs_info.used_size+used_num;
            }
            p_para->total_num = entry_num;
            p_para->used_num = used_num;
            break;
        case CTC_DIAG_TYPE_SRAM_SCL:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,CTC_DIAG_SUB_TYPE_TUNNEL_DECP);
            if(p_para->sub_type < CTC_DIAG_SUB_TYPE_SCL)
            {
                CTC_ERROR_RETURN(sys_usw_scl_get_resource_by_priority(lchip, CTC_INGRESS, 1, p_para->sub_type, &p_para->total_num, &p_para->used_num));
                break;
            }

            sal_memset(&p_ftm_info, 0, sizeof(drv_ftm_info_detail_t));
            p_ftm_info.info_type = DRV_FTM_INFO_TYPE_SCL_MODE;
            CTC_ERROR_RETURN(drv_usw_ftm_get_info_detail(lchip, &p_ftm_info));
            drv_usw_ftm_get_entry_num(lchip, DsUserIdMacHashKey_t, &entry_num);
            if(DRV_FROM_TMM(lchip) || (DRV_IS_TSINGMA(lchip) &&!p_ftm_info.scl_mode))
            {
                drv_usw_ftm_get_entry_num(lchip, DsUserId1MacHashKey_t, &entry_num1);
                entry_num += entry_num1;
            }

            if(p_para->sub_type == CTC_DIAG_SUB_TYPE_SCL)
            {
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_SCL,&specs_info);
            }
            else if (p_para->sub_type == CTC_DIAG_SUB_TYPE_SCL_FLOW)
            {
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_SCL_FLOW,&specs_info);
            }
            else
            {
                sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_TUNNEL,&specs_info);
            }
            p_para->total_num = entry_num;
            p_para->used_num = specs_info.used_size;
            break;

        case CTC_DIAG_TYPE_SRAM_VLAN_XLATE:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,MCHIP_CAP(SYS_CAP_SCL_HASH_NUM));
            CTC_ERROR_RETURN(sys_usw_scl_get_resource_by_priority(lchip, CTC_EGRESS, 1, p_para->sub_type, &p_para->total_num, &p_para->used_num));
            break;
        case CTC_DIAG_TYPE_SRAM_ACL:
            drv_usw_ftm_get_entry_num(lchip, DsFlowL2HashKey_t, &entry_num);
            cam_num = FLOW_HASH_CAM_NUM;
            sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_ACL_FLOW,&specs_info);
            p_para->total_num = (entry_num+cam_num);
            p_para->used_num = specs_info.used_size;
            break;

        case CTC_DIAG_TYPE_SRAM_MPLS:
            drv_usw_ftm_get_entry_num(lchip, DsMplsLabelHashKey_t, &entry_num);
            cam_num = 64;
            sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_MPLS,&specs_info);
            p_para->total_num = (entry_num+cam_num);
            p_para->used_num = specs_info.used_size;
            break;

        case CTC_DIAG_TYPE_SRAM_OAM_MEP:
            if (DRV_FROM_TMM(lchip))
            {
                drv_usw_ftm_get_entry_num(lchip, DsEthMep_t, &entry_num);
            }
            else
            {
            drv_usw_ftm_get_entry_num(lchip, DsBfdMep_t, &entry_num);
            }
            sys_usw_ftm_process_callback(lchip,CTC_FTM_SPEC_OAM,&specs_info);
            p_para->total_num = entry_num;
            p_para->used_num = specs_info.used_size*2;
            break;

        case CTC_DIAG_TYPE_SRAM_OAM_KEY:
            if (DRV_FROM_TMM(lchip))
            {
                drv_usw_ftm_get_entry_num(lchip, DsOamEthHashKey_t, &entry_num);
            }
            else
            {
            drv_usw_ftm_get_entry_num(lchip, DsBfdMep_t, &entry_num);
            }
            sys_usw_oam_get_used_key_count(lchip,&specs_info.used_size);
            p_para->total_num = entry_num;
            p_para->used_num = specs_info.used_size;
            break;

        case CTC_DIAG_TYPE_SRAM_APS:
            sys_usw_aps_ftm_cb(lchip, &specs_info.used_size);
            drv_usw_ftm_get_entry_num(lchip, DRV_FROM_AT(lchip)?DsIpeApsBridge_t : DsApsBridge_t,&entry_num);
            p_para->total_num = (entry_num+cam_num);
            p_para->used_num = specs_info.used_size;
            break;

        case CTC_DIAG_TYPE_TCAM_INGRESS_ACL:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM)-1);
            sys_usw_acl_get_resource_by_priority(lchip,p_para->sub_type,0,&p_para->total_num,&p_para->used_num);
            break;

        case CTC_DIAG_TYPE_TCAM_EGRESS_ACL:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,MCHIP_CAP(SYS_CAP_ACL_EGRESS_LKUP_NUM)-1);
            sys_usw_acl_get_resource_by_priority(lchip,p_para->sub_type,1,&p_para->total_num,&p_para->used_num);
            break;

        case CTC_DIAG_TYPE_TCAM_SCL:
            if (DRV_FROM_TMM(lchip))
            {
                CTC_VALUE_RANGE_CHECK(p_para->sub_type, 2, 3);
            }
            else
            {
            CTC_MAX_VALUE_CHECK(p_para->sub_type,3);
            }
#define DIAG_SCL_FPA_SIZE 80
            sys_usw_scl_get_resource_by_priority(lchip, CTC_INGRESS, 0, p_para->sub_type, &p_para->total_num, &p_para->used_num);
            break;

        case CTC_DIAG_TYPE_TCAM_LPM:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,CTC_DIAG_SUB_TYPE_IPV6);
            sys_usw_ipuc_get_tcam_memusage(lchip,p_para->sub_type,&p_para->total_num,&p_para->used_num);
            break;

        case CTC_DIAG_TYPE_SRAM_NEXTHOP:
            CTC_MAX_VALUE_CHECK(p_para->sub_type,CTC_DIAG_SUB_TYPE_EDIT2);
            if(p_para->sub_type == 0)
            {
                for(loop = 0; loop < (sizeof(edit_name)/sizeof(edit_name[0])); loop++)
                {
                    if(0 != edit_name[loop][0])
                    {
                        drv_usw_ftm_get_entry_num(lchip, edit_name[loop][0], &entry_num1);
                    }

                    if(SYS_API_NH_NUM != edit_name[loop][1])
                    {
                        sys_usw_nh_get_nh_resource(lchip, edit_name[loop][1],&used_num);
                        specs_info.used_size += used_num;
                    }                   
                    if(edit_name[loop][1] == SYS_API_NH_DSFWD1 || edit_name[loop][1] == SYS_API_NH_DSFWD )
                    {
                        entry_num += entry_num1*2;
                    }
                    else
                    {
                        entry_num += entry_num1;
                    }
                    entry_num1 = 0;
                    
                }
                entry_num += 2048;
            }
            else if(p_para->sub_type == CTC_DIAG_SUB_TYPE_FWD)
            {
                drv_usw_ftm_get_entry_num(lchip, DsFwd_t, &entry_num);
                entry_num = entry_num * 2;
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_DSFWD,&specs_info.used_size);
            }
            else if(p_para->sub_type == CTC_DIAG_SUB_TYPE_MET)
            {
                if(DRV_FROM_AT(lchip))
                {
                    drv_usw_ftm_get_entry_num(lchip, DsMet_t, &entry_num);
                    drv_usw_ftm_get_entry_num(lchip, DsMetEntrySlim1X_t, &entry_num1);
                    entry_num += entry_num1;
                }
                else
                {
                    drv_usw_ftm_get_entry_num(lchip, DsMetEntry3W_t, &entry_num);
                }
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_DSMET,&specs_info.used_size);
            }
            else if(p_para->sub_type == CTC_DIAG_SUB_TYPE_NEXTHOP)
            {
                drv_usw_ftm_get_entry_num(lchip, DsNextHop4W_t, &entry_num);
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_NEXTHOP_4W,&specs_info.used_size);
            }
            else if(p_para->sub_type == CTC_DIAG_SUB_TYPE_EDIT)
            {
                drv_usw_ftm_get_entry_num(lchip, (DRV_FROM_TMM(lchip) ? DsL2EditAddEth1X_t : DsL2EditEth3W_t), &entry_num);
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_L2EDIT, &used_num);
                specs_info.used_size = specs_info.used_size + used_num;
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_L3EDIT, &used_num);
                specs_info.used_size = specs_info.used_size + used_num;
            }
            else if (p_para->sub_type == CTC_DIAG_SUB_TYPE_SPME)
            {
                entry_num = 1024;
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_L3EDIT_SPME, &specs_info.used_size);
            }
            else if(p_para->sub_type == CTC_DIAG_SUB_TYPE_OUT_EDIT)
            {
                entry_num = 1024;
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_L2EDIT_OUTER_4W, &specs_info.used_size);
            }
            else if(p_para->sub_type == CTC_DIAG_SUB_TYPE_FWD2)
            {
                drv_usw_ftm_get_entry_num(lchip, DsFwd1_t, &entry_num);
                entry_num = entry_num * 2;
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_DSFWD1,&specs_info.used_size);
            }
            else if(p_para->sub_type == CTC_DIAG_SUB_TYPE_EDIT2)
            {
                drv_usw_ftm_get_entry_num(lchip, DsL2EditAddEth1X0_t, &entry_num);
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_L2EDIT_INNER, &used_num);
                specs_info.used_size = specs_info.used_size + used_num;
                sys_usw_nh_get_nh_resource(lchip, SYS_API_NH_L3EDIT_INNER, &used_num);
                specs_info.used_size = specs_info.used_size + used_num;
            }
            else
            {
                return CTC_E_INVALID_PARAM;
            }
            p_para->total_num = entry_num;
            p_para->used_num = specs_info.used_size;
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}
#define SYS_USW_DIAG_LPM_TCAM_ADDR(lchip) DRV_FROM_TMM(lchip) ? (0x4c200001):(0x04100001)
#define SYS_USW_DIAG_FLOW_TCAM_ADDR(lchip) (0x02400001)
#define SYS_USW_DIAG_BIST_LPM_TCAM_SIZE(lchip)           (DRV_FROM_TMM(lchip)? 4096:1024)
#define SYS_USW_DIAG_PATTERN_NUM 10

typedef struct sys_usw_diag_test_pattern_s
{
    uint32 data0;
    uint32 data1;
    uint32 mask0;
    uint32 mask1;
    uint32 valid_bit0;
    uint32 valid_bit1;
}
sys_usw_diag_test_pattern_t;

sys_usw_diag_test_pattern_t sys_usw_diag_test_pattern[SYS_USW_DIAG_PATTERN_NUM] =
{
    /*entry0 data,  entry1 data, mask0, mask1, entry 0 valid bit, entry 1 valid bit*/
    {0x55555555, 0xAAAAAAAA, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x80000000},
    {0xAAAAAAAA, 0x55555555, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x80000000},
    {0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x80000000},
    {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x80000000},

    {0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x80000000, 0x80000000}, /*case 7*/
    {0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, 0x80000000, 0x80000000}, /*case 8*/

    /*Below is no need to use another wrapper*/
    {0x55555555, 0xAAAAAAAA, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0x80000000},
    {0x55555555, 0xAAAAAAAA, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0},

    {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x80000000},
    {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x80000000},

};
typedef struct sys_usw_diag_req_key_s
{
    uint8 req_key_num;
    uint8 shift_en;
    struct
    {
        uint32 req_key;
        uint32 excp_hit0:1;
        uint32 excp_hit1:1;
        uint32 rsv:30;
    }round[3];
}
sys_usw_diag_req_key_t;
sys_usw_diag_req_key_t sys_usw_diag_req_key[SYS_USW_DIAG_PATTERN_NUM] =
{
    {2, 0, {{0x55555555, 1, 0}, {0xAAAAAAAA, 0, 1}, {0}}},
    {2, 0, {{0x55555555, 0, 1}, {0xAAAAAAAA, 1, 0}, {0}}},
    {2, 0, {{0x00000000, 1, 0}, {0xFFFFFFFF, 0, 1}, {0}}},
    {2, 0, {{0x00000000, 0, 1}, {0xFFFFFFFF, 1, 0}, {0}}},

    {3, 0, {{0xFFFFFFFF, 1, 1}, {0x55555555, 1, 0}, {0xAAAAAAAA, 0, 1}}},
    {3, 0, {{0xFFFFFFFF, 1, 1}, {0xAAAAAAAA, 1, 0}, {0x55555555, 0, 1}}},

    {2, 0, {{0x55555555, 0, 0}, {0xAAAAAAAA, 0, 1}, {0}}},
    {2, 0, {{0x55555555, 1, 0}, {0xAAAAAAAA, 0, 0}, {0}}},

    {1, 1, {{0x1, 0, 0},{0}}},
    {1, 1, {{0x0, 0, 0},{0}}},
};
extern int32
drv_usw_chip_write_sram_entry(uint8 lchip, uintptr addr, uint32* data, int32 len);
int32
_sys_tm_diag_bist_mem_delete(uint8 lchip, sys_usw_diag_bist_tcam_t type, uint32 tbl_index, uint32 end_index)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 i = 0;
    FlowTcamTcamMem_m  flow_tcam_mem;
    LpmTcamTcamMem_m  lpm_tcam_mem;
    IpeCidTcamMem_m   cid_tcam_mem;
    QMgrEnqTcamMem_m  enque_tcam_mem;
    sal_memset(&flow_tcam_mem, 0 , sizeof(FlowTcamTcamMem_m));
    sal_memset(&lpm_tcam_mem, 0 , sizeof(LpmTcamTcamMem_m));
    sal_memset(&cid_tcam_mem, 0 , sizeof(IpeCidTcamMem_m));
    sal_memset(&enque_tcam_mem, 0 , sizeof(QMgrEnqTcamMem_m));
    switch (type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            for (i = tbl_index; i < end_index; i++)
            {
                cmd = DRV_IOW(FlowTcamTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, cmd, &flow_tcam_mem);
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            for (i = tbl_index; i < end_index; i++)
            {
                cmd = DRV_IOW(LpmTcamTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, cmd, &lpm_tcam_mem);
            }
            break;
        case SYS_USW_DIAG_BIST_CID_TCAM:
            for (i = tbl_index; i < end_index; i++)
            {
                cmd = DRV_IOW(IpeCidTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, cmd, &cid_tcam_mem);
            }
            break;
        case SYS_USW_DIAG_BIST_ENQUEUE_TCAM:
            for (i = tbl_index; i < end_index; i++)
            {
                cmd = DRV_IOW(QMgrEnqTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, cmd, &enque_tcam_mem);
            }
            break;
        default:
            break;
    }
    return ret;
}
int32
_sys_tm_diag_bist_tcam_prepare(uint8 lchip, sys_usw_diag_bist_tcam_t type,
                                                            uint8  test_pattern,
                                                            uint32 start_idx,
                                                            uint32 end_idx,
                                                            uint8 step)
{
    int32 ret = CTC_E_NONE;
    uint32 index   = 0;
    uint32 ds[7] = {0};
    uint8  select;
    uint32  address;
    uint32  address_base;
    switch (type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            address_base = SYS_USW_DIAG_FLOW_TCAM_ADDR(lchip);
            for (index = start_idx; index < end_idx; index += step)
            {
                select = ((index/step*step)%(2*step)) ? 1:0;
                ds[0] = select ? sys_usw_diag_test_pattern[test_pattern].data1 : sys_usw_diag_test_pattern[test_pattern].data0;
                ds[1] = select ? sys_usw_diag_test_pattern[test_pattern].data1 : sys_usw_diag_test_pattern[test_pattern].data0;
                ds[2] = select ? sys_usw_diag_test_pattern[test_pattern].data1 : sys_usw_diag_test_pattern[test_pattern].data0;

                ds[3] = select ? sys_usw_diag_test_pattern[test_pattern].mask1 : sys_usw_diag_test_pattern[test_pattern].mask0;
                ds[4] = select ? sys_usw_diag_test_pattern[test_pattern].mask1 : sys_usw_diag_test_pattern[test_pattern].mask0;
                ds[5] = select ? sys_usw_diag_test_pattern[test_pattern].mask1 : sys_usw_diag_test_pattern[test_pattern].mask0;

                ds[6] = (select ? sys_usw_diag_test_pattern[test_pattern].valid_bit1: sys_usw_diag_test_pattern[test_pattern].valid_bit0);
                address = (address_base + index*32);
                drv_usw_chip_write_sram_entry(lchip, address, ds, 28);
            }
            break;

        case SYS_USW_DIAG_BIST_LPM_TCAM:
            address_base = SYS_USW_DIAG_LPM_TCAM_ADDR(lchip);
            for (index = start_idx; index < end_idx; index += step)
            {
                select = ((index/step*step)%(2*step)) ? 1:0;
                ds[0] = select ? sys_usw_diag_test_pattern[test_pattern].data1 : sys_usw_diag_test_pattern[test_pattern].data0;
                ds[1] = (select ? sys_usw_diag_test_pattern[test_pattern].data1 : sys_usw_diag_test_pattern[test_pattern].data0)&0x3FFF;

                ds[2] = select ? sys_usw_diag_test_pattern[test_pattern].mask1 : sys_usw_diag_test_pattern[test_pattern].mask0;
                ds[3] = (select ? sys_usw_diag_test_pattern[test_pattern].mask1 : sys_usw_diag_test_pattern[test_pattern].mask0)&0x3FFF;
                if(select ? sys_usw_diag_test_pattern[test_pattern].valid_bit1: sys_usw_diag_test_pattern[test_pattern].valid_bit0)
                {
                   ds[3] = ds[3] | 0x80000000;
                }

                address = (address_base + index*16);
                drv_usw_chip_write_sram_entry(lchip, address, ds, 16);
            }
            break;
        default:
            break;
    }

    return ret;
}
int32
_sys_tm_diag_bist_lpm_tcam_prepare(uint8 lchip, sys_usw_diag_bist_tcam_t type,
                                                            uint8  test_pattern,
                                                            uint32 start_idx,
                                                            uint32 end_idx,
                                                            uint8 step)
{
    uint32 index   = 0;
    uint32 ds[4] = {0};
    uint8  select;
    uint32  address;
    uint32  address_base = SYS_USW_DIAG_LPM_TCAM_ADDR(lchip);


    for (index = start_idx; index < end_idx; index += step)
    {
        select = ((index/step*step)%(2*step)) ? 1:0;
        ds[0] = select ? sys_usw_diag_test_pattern[test_pattern].data1 : sys_usw_diag_test_pattern[test_pattern].data0;
        ds[1] = select ? sys_usw_diag_test_pattern[test_pattern].data1 : sys_usw_diag_test_pattern[test_pattern].data0;

        ds[2] = select ? sys_usw_diag_test_pattern[test_pattern].mask1 : sys_usw_diag_test_pattern[test_pattern].mask0;
        ds[3] = (select ? sys_usw_diag_test_pattern[test_pattern].mask1 : sys_usw_diag_test_pattern[test_pattern].mask0) & 0x3FFF;
        ds[3] |= 0x80000000;

        address = (address_base + index*16);
        drv_usw_chip_write_sram_entry(lchip, address, ds, 16);
    }
    return CTC_E_NONE;
}
int32
_sys_usw_diag_bist_reset_tcam_valid_bit(uint8 lchip, sys_usw_diag_bist_tcam_t mem_type)
{
    uint32 cmd;
    uint32 tmp_value;
 
    if(mem_type == SYS_USW_DIAG_BIST_FLOW_TCAM)
    {
        cmd = DRV_IOW(FlowTcamTcamVaidBitReset_t, FlowTcamTcamVaidBitReset_tcamValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_LPM_TCAM)
    {
        cmd = DRV_IOW(LpmTcamTcamVaidBitReset_t, LpmTcamTcamVaidBitReset_tcamValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_CID_TCAM)
    {
        cmd = DRV_IOW(IpeAclTcamValidBitReset_t, IpeAclTcamValidBitReset_tcamValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_EGRACL_TCAM)
    {
        cmd = DRV_IOW(EgessAclTcamBitReset_t, EgessAclTcamBitReset_tcamValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM)
    { 
        cmd = DRV_IOW(EgrSclHashTcamValidBitReset_t, EgrSclHashTcamValidBitReset_tcam0ValidBitReset_f);
        tmp_value = 1;
        DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);

        tmp_value = 0;
        DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);

        cmd = DRV_IOW(EgrSclHashTcamValidBitReset_t, EgrSclHashTcamValidBitReset_tcam1ValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM)
    {
        cmd = DRV_IOW(IpeHdrAdjRouterMacTcamValidBitReset_t, IpeHdrAdjRouterMacTcamValidBitReset_tcamValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM)
    {
        cmd = DRV_IOW(IpeHdrAdjUdfTcamValidBitReset_t, IpeHdrAdjUdfTcamValidBitReset_udfTcamValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_USERIDHASH_TCAM)
    {
        cmd = DRV_IOW(UserIdHashTcamBitReset_t, UserIdHashTcamBitReset_tcam0ValidBitReset_f);
        tmp_value = 1;
        DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);

        tmp_value = 0;
        DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);
        
        cmd = DRV_IOW(UserIdHashTcamBitReset_t, UserIdHashTcamBitReset_tcam1ValidBitReset_f);
    }
    else if(mem_type == SYS_USW_DIAG_BIST_USERID_TCAM)
    {
        cmd = DRV_IOW(UserIdTcamBitReset_t, UserIdTcamBitReset_tcam0ValidBitReset_f);
        tmp_value = 1;
        DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);

        tmp_value = 0;
        DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);
        cmd = DRV_IOW(UserIdTcamBitReset_t, UserIdTcamBitReset_tcam1ValidBitReset_f);
    }
    else
    {
        cmd = DRV_IOW(QMgrEnqTcamValidBitReset_t, IpeAclTcamValidBitReset_tcamValidBitReset_f);
    }

    tmp_value = 1;
    DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);

    tmp_value = 0;
    DRV_FIELD_IOCTL(lchip, 0, cmd, &tmp_value);
    
    return CTC_E_NONE;
}

int32
_sys_tm_diag_bist_flow_tcam_req_prepare(uint8 lchip, uint8 wrapper, uint8 test_pattern, uint8 round, uint8 shift, uint8 key_size)
{
    uint32 cmd = 0;
    uint8  loop = 0;
    FlowTcamBistReqFA_m  flow_tcam_req;
    uint32* p_flow_tcam_req = (uint32*)&flow_tcam_req;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_FLOW_REQ_MEM; loop++)
    {
        sal_memset(&flow_tcam_req, 0 , sizeof(FlowTcamBistReqFA_m));
        if(sys_usw_diag_req_key[test_pattern].shift_en)
        {
            if(sys_usw_diag_req_key[test_pattern].round[round].req_key)
            {
                CTC_BMP_SET(p_flow_tcam_req, shift);
            }
            else
            {
                p_flow_tcam_req[0] = 0xFFFFFFFF;
                p_flow_tcam_req[1] = 0xFFFFFFFF;
                p_flow_tcam_req[2] = 0xFFFF;
                CTC_BMP_UNSET(p_flow_tcam_req, shift);
            }
            p_flow_tcam_req[3] = p_flow_tcam_req[0];
            p_flow_tcam_req[4] = p_flow_tcam_req[1];
            p_flow_tcam_req[5] = p_flow_tcam_req[2];
        }
        else
        {
            p_flow_tcam_req[0] = sys_usw_diag_req_key[test_pattern].round[round].req_key;
            p_flow_tcam_req[1] = sys_usw_diag_req_key[test_pattern].round[round].req_key;
            p_flow_tcam_req[2] = sys_usw_diag_req_key[test_pattern].round[round].req_key&0xFFFF;
            if((wrapper & 0x01) == 1)
            {
                p_flow_tcam_req[3] = p_flow_tcam_req[0];
                p_flow_tcam_req[4] = p_flow_tcam_req[1];
                p_flow_tcam_req[5] = p_flow_tcam_req[2];
                p_flow_tcam_req[0] = (0x5A5A5A<<8)|(loop<<1);
                p_flow_tcam_req[1] = 0x5A5A5A5A;
                p_flow_tcam_req[2] = 0x5A5A;

            }
            else
            {
                p_flow_tcam_req[3] = (0x5A5A5A<<8)|(loop<<1);
                p_flow_tcam_req[4] = 0x5A5A5A5A;
                p_flow_tcam_req[5] = 0x5A5A;
            }
        }

        p_flow_tcam_req[6] = p_flow_tcam_req[0];
        p_flow_tcam_req[7] = p_flow_tcam_req[1];
        p_flow_tcam_req[8] = p_flow_tcam_req[2];

        p_flow_tcam_req[9] = p_flow_tcam_req[3];
        p_flow_tcam_req[10] = p_flow_tcam_req[4];
        p_flow_tcam_req[11] = p_flow_tcam_req[5];
        SetFlowTcamBistReqFA(V,bistReqKeyEnd_f,   &flow_tcam_req, 1);
        SetFlowTcamBistReqFA(V,bistReqKeySize_f,  &flow_tcam_req, key_size);
        SetFlowTcamBistReqFA(V,bistReqKeyValid_f, &flow_tcam_req, 1);
        cmd = DRV_IOW(FlowTcamBistReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &flow_tcam_req);
    }
    return CTC_E_NONE;
}
int32
_sys_tm_diag_bist_lpm_tcam_req_prepare(uint8 lchip, uint8 wrapper, uint8 test_pattern, uint8 round, uint8 shift, uint8 key_size)
{
    uint32 cmd = 0;
    uint8  loop = 0;
    LpmTcamBistReq0FA_m  lpm_tcam_req;
    uint32* p_lpm_tcam_req = (uint32*)&lpm_tcam_req;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_LPM_REQ_MEM; loop++)
    {
        sal_memset(&lpm_tcam_req, 0 , sizeof(LpmTcamBistReq0FA_m));
        if(sys_usw_diag_req_key[test_pattern].shift_en)
        {
            if(sys_usw_diag_req_key[test_pattern].round[round].req_key)
            {
                CTC_BMP_SET(p_lpm_tcam_req, shift);
            }
            else
            {
                p_lpm_tcam_req[0] = 0xFFFFFFFF;
                p_lpm_tcam_req[1] = 0x3FFF;
                CTC_BMP_UNSET(p_lpm_tcam_req, shift);
            }
            p_lpm_tcam_req[2] = p_lpm_tcam_req[0];
            p_lpm_tcam_req[3] = p_lpm_tcam_req[1];
        }
        else
        {
            p_lpm_tcam_req[0] = sys_usw_diag_req_key[test_pattern].round[round].req_key;
            p_lpm_tcam_req[1] = sys_usw_diag_req_key[test_pattern].round[round].req_key&0x3FFF;
            if((wrapper & 0x01) == 1)
            {
                p_lpm_tcam_req[2] = p_lpm_tcam_req[0];
                p_lpm_tcam_req[3] = p_lpm_tcam_req[1];

                p_lpm_tcam_req[0] = (0x5A5A5A<<8)|(loop<<1);
                p_lpm_tcam_req[1] = 0x1A5A;

            }
            else
            {
                p_lpm_tcam_req[2] = (0x5A5A5A<<8)|(loop<<1);
                p_lpm_tcam_req[3] = 0x1A5A;
            }
        }

        p_lpm_tcam_req[4] = p_lpm_tcam_req[0];
        p_lpm_tcam_req[5] = p_lpm_tcam_req[1];

        p_lpm_tcam_req[6] = p_lpm_tcam_req[2];
        p_lpm_tcam_req[7] = p_lpm_tcam_req[3];
        SetLpmTcamBistReq0FA(V,bistReqKeySize_f,  &lpm_tcam_req, key_size);
        SetLpmTcamBistReq0FA(V,bistReqKeyValid_f, &lpm_tcam_req, 1);
        cmd = DRV_IOW(LpmTcamBistReq0FA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &lpm_tcam_req);

        cmd = DRV_IOW(LpmTcamBistReq1FA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &lpm_tcam_req);

        cmd = DRV_IOW(LpmTcamBistReq2FA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &lpm_tcam_req);
    }
    return CTC_E_NONE;
}
int32 _sys_tm_diag_bist_req_prepare(uint8 lchip, uint8 type, uint8 wrapper, uint8 test_pattern, uint8 round, uint8 shift, uint8 key_size)
{
    switch (type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            return _sys_tm_diag_bist_flow_tcam_req_prepare(lchip, wrapper, test_pattern, round, shift, key_size);
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            return _sys_tm_diag_bist_lpm_tcam_req_prepare(lchip, wrapper, test_pattern, round, shift, key_size);

        default:
            break;
    }
    return CTC_E_NONE;
}

int32
_sys_tm_diag_bist_flow_tcam_result(uint8 lchip, tcam_bist_param_t* p_param, tcam_bist_result_t* p_result)
{
    uint16 local_idx;
    uint8 loop;
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8  error_flag = 0;
    FlowTcamBistResultFA_m     flow_bist_result;
    uint8  excp_hit;
    uint8  select;
    uint16 index = p_param->index;
    uint16 error_index;
    for (loop = 0; loop < p_param->req_num; loop++)
    {
        error_flag = 0;
        select = ((index/p_param->step*p_param->step)%(2*p_param->step)) ? 1:0;
        excp_hit = select ? sys_usw_diag_req_key[p_param->pattern].round[p_param->round].excp_hit1 : \
                                            sys_usw_diag_req_key[p_param->pattern].round[p_param->round].excp_hit0;

        sal_memset(&flow_bist_result, 0 , sizeof(FlowTcamBistResultFA_m));
        cmd = DRV_IOR(FlowTcamBistResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &flow_bist_result);
        GetFlowTcamBistResultFA(A, realIndexHit_f, &flow_bist_result, &field_value);

        if(excp_hit)
        {
            if (field_value)
            {
                GetFlowTcamBistResultFA(A,realIndex_f, &flow_bist_result, &field_value);
                if(field_value != index)
                {
                    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Tcam hit error, expect index[%d], actual index[%d]!!!!!\n", index, field_value);
                    ret = CTC_E_HW_FAIL;
                    error_flag = 1;
                }
            }
            else
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Flow-tcam Not Hit! expect index[%d]\n", index);
                ret = CTC_E_HW_TIME_OUT;
                error_flag = 1;
            }
            error_index = index;
        }
        else
        {
            if (field_value)
            {
                GetFlowTcamBistResultFA(A,realIndex_f, &flow_bist_result, &field_value);
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Not expect index, actual hit index[%u]\n", field_value);
                ret = CTC_E_HW_TIME_OUT;
                error_flag = 1;
                error_index = field_value;
            }
        }

        if (error_flag)
        {
            if(p_result->first_err_idx == 0xFFFF)
            {
                p_result->first_err_idx = field_value;
            }
            local_idx = error_index % 2048;
            if(0 == (*p_result->p_bmp)[local_idx>>5])
            {
                (*p_result->p_bmp)[local_idx>>5] = 0xFFFFFFFF;
                (*p_result->err_entry_cnt)++;
            }
        }
        index += p_param->step;
    }
    return ret;
}

int32
_sys_tm_diag_bist_lpm_tcam_result(uint8 lchip, tcam_bist_param_t* p_param, tcam_bist_result_t* p_result)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8  error_flag = 0;
    uint16 index = p_param->index;
    uint8  excp_hit;
    uint8  select;
    uint16 local_idx;
    LpmTcamBistResult0FA_m     lpm_bist_result;
    uint16 error_index;

    if (0 == p_param->lpm_id)
    {
        cmd = DRV_IOR(LpmTcamBistResult0FA_t, DRV_ENTRY_FLAG);
    }
    else if (1 == p_param->lpm_id)
    {
        cmd = DRV_IOR(LpmTcamBistResult1FA_t, DRV_ENTRY_FLAG);
    }
    else
    {
        cmd = DRV_IOR(LpmTcamBistResult2FA_t, DRV_ENTRY_FLAG);
    }
    for (loop = 0; loop < p_param->req_num; loop++)
    {
        error_flag = 0;
        select = ((index/p_param->step*p_param->step)%(2*p_param->step)) ? 1:0;
        excp_hit = select ? sys_usw_diag_req_key[p_param->pattern].round[p_param->round].excp_hit1 : \
                                            sys_usw_diag_req_key[p_param->pattern].round[p_param->round].excp_hit0;

        DRV_IOCTL(lchip, loop, cmd, &lpm_bist_result);
        GetLpmTcamBistResult0FA(A,realIndex0Hit_f, &lpm_bist_result, &field_value);
        if(excp_hit)
        {
            if (field_value)
            {
                GetLpmTcamBistResult0FA(A,realIndex0_f, &lpm_bist_result, &field_value);
                if (index != field_value)
                {
                    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Tcam hit error, expect index[%d], actual index[%d]!!!!!\n", index, field_value);
                    ret = CTC_E_HW_FAIL;
                    error_flag = 1;
                }
            }
            else
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST lpm-tcam Not Hit! expect index[%d]\n", index);
                ret = CTC_E_HW_TIME_OUT;
                error_flag = 1;
            }
            error_index = index;
        }
        else
        {
            if (field_value)
            {
                GetLpmTcamBistResult0FA(A,realIndex0_f, &lpm_bist_result, &field_value);
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Not expect index, actual hit index[%u]\n", field_value);
                ret = CTC_E_HW_TIME_OUT;
                error_flag = 1;
                error_index = field_value;
            }
        }

        if (error_flag)
        {
            if(p_result->first_err_idx == 0xFFFF)
            {
                p_result->first_err_idx = field_value;
            }

            if(p_param->lpm_id < 2)
            {
                local_idx = error_index % (SYS_USW_DIAG_BIST_LPM_TCAM_SIZE(lchip));
            }
            else
            {
                local_idx = error_index % (2*SYS_USW_DIAG_BIST_LPM_TCAM_SIZE(lchip));
            }
            if(0 == ((*p_result->p_bmp)[local_idx>>5]))
            {
                (*p_result->p_bmp)[local_idx>>5] = 0xFFFFFFFF;
                (*p_result->err_entry_cnt)++;
            }
        }
        index += p_param->step;
    }

    return ret;
}
/*ext data : flow mem id or lpm id*/
int32
_sys_tm_diag_bist_trigger(uint8 lchip, sys_usw_diag_bist_tcam_t type, uint8 enable, uint32 ext_data)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 enable_u32 = 0;
    FlowTcamBistCtl_m     flow_bist_ctl;

    sal_memset(&flow_bist_ctl, 0 , sizeof(FlowTcamBistCtl_m));
    switch (type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
        {
            uint16 mem_sel;
            uint16 flow_mem_id = ext_data;
            uint8  mem_sel_2_flow_mem_id[4][4] = {
                {2, 4, 8, 0xFF},
                {3, 5, 9, 0xFF},
                {6, 10, 0xFF, 0xFF},
                {7, 11, 0xFF, 0xFF}
            };
            if(flow_mem_id >= 15)
            {
                FlowTcamLookupCtl_m flow_ctl;
                cmd = DRV_IOR(FlowTcamLookupCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, &flow_ctl);
                mem_sel = GetFlowTcamLookupCtl(V, share0IntfSel_f+(flow_mem_id-15), &flow_ctl);
                CTC_BIT_SET(enable_u32, mem_sel_2_flow_mem_id[(flow_mem_id-15)][mem_sel]);
            }
            else
            {
                CTC_BIT_SET(enable_u32, flow_mem_id);
            }
            SetFlowTcamBistCtl(V,cfgBistEn_f, &flow_bist_ctl, enable ? enable_u32:0);
            SetFlowTcamBistCtl(V,cfgBistOnce_f, &flow_bist_ctl, 1);
            SetFlowTcamBistCtl(V,cfgCaptureIndexDly_f, &flow_bist_ctl, 1);
            cmd = DRV_IOW(FlowTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &flow_bist_ctl);
            break;
        }
        case SYS_USW_DIAG_BIST_LPM_TCAM:
        {
            uint32 bist_en_field_id;
            uint32 bist_once_field_id;
            uint32 bist_delay_field_id;

            if(ext_data == 0)
            {
                bist_en_field_id = LpmTcamBistCtrl_cfgDaSa0BistEn_f;
                bist_once_field_id = LpmTcamBistCtrl_cfgDaSa0BistOnce_f;
                bist_delay_field_id = LpmTcamBistCtrl_cfgCaptureIndexDly_f;
            }
            else if(ext_data == 1)
            {
                bist_en_field_id = LpmTcamBistCtrl_cfgDaSa1BistEn_f;
                bist_once_field_id = LpmTcamBistCtrl_cfgDaSa1BistOnce_f;
                bist_delay_field_id = LpmTcamBistCtrl_cfgCaptureIndexDly_f;
            }
            else
            {
                bist_en_field_id = LpmTcamBistCtrl_cfgShareBistEn_f;
                bist_once_field_id = LpmTcamBistCtrl_cfgShareBistOnce_f;
                bist_delay_field_id = LpmTcamBistCtrl_cfgCaptureIndexDly_f;
            }

            field_val = enable;
            cmd = DRV_IOW(LpmTcamBistCtrl_t, bist_en_field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
            if (enable == 0)
            {
                field_val = 1;
                cmd = DRV_IOW(LpmTcamBistCtrl_t, bist_once_field_id);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
                field_val = 4;
                cmd = DRV_IOW(LpmTcamBistCtrl_t, bist_delay_field_id);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
            }
            break;
        }
        default:
            break;
    }
    return ret;
}

int32
_sys_tm_diag_bist_done(uint8 lchip, sys_usw_diag_bist_tcam_t type, uint32 lpm_id)
{
    int32  ret = CTC_E_NONE;
    uint8  wait_cnt = 0;
    uint32 done    = 0;
    uint32 cmd  = 0;
    switch (type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            cmd= DRV_IOR(FlowTcamBistStatus_t, FlowTcamBistStatus_bistDone_f);
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            if(lpm_id == 0)
            {
                cmd = DRV_IOR(LpmTcamBistStatus_t, LpmTcamBistStatus_daSa0BistDone_f);
            }
            else if(lpm_id == 1)
            {
                cmd= DRV_IOR(LpmTcamBistStatus_t, LpmTcamBistStatus_daSa1BistDone_f);
            }
            else
            {
                cmd= DRV_IOR(LpmTcamBistStatus_t, LpmTcamBistStatus_shareBistDone_f);
            }
            break;
        default:
            break;
    }
    while (1)
    {
        DRV_FIELD_IOCTL(lchip, 0, cmd, &done);
        if (done)
        {
            return CTC_E_NONE;
        }
        else
        {
            wait_cnt++;
            if (10 == wait_cnt)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "TCAM BIST OUT OF TIME!\n");
                return CTC_E_HW_TIME_OUT;
            }
            sal_task_sleep(1);
        }
    }
    return ret;
}

int32
_sys_tm_diag_bist_check_result(uint8 lchip, tcam_bist_param_t* p_param, tcam_bist_result_t* p_result)
{
    switch(p_param->type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            return _sys_tm_diag_bist_flow_tcam_result(lchip, p_param, p_result);
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            return _sys_tm_diag_bist_lpm_tcam_result(lchip, p_param, p_result);
            break;
        default:
            break;
    }
    return CTC_E_NONE;
}
int32
_sys_tm_diag_bist_cmp_and_result(uint8 lchip, uint32 start_idx, uint32 end_idx, uint8 wrapper, tcam_bist_param_t* p_param, tcam_bist_result_t* p_result)
{
    uint32 excp_index;
    uint32 wrapper_index;
    int32 ret = CTC_E_NONE;
    uint32 index = 0;
    uint8 req_num=0;
    uint32 ext_data = 0;
    switch(p_param->type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            req_num = SYS_USW_DIAG_BIST_FLOW_REQ_MEM;
            ext_data = start_idx/SYS_USW_DIAG_BIST_FLOW_RAM_SZ;
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            req_num = SYS_USW_DIAG_BIST_LPM_REQ_MEM;
            ext_data = (end_idx <= (TABLE_MAX_INDEX(lchip, LpmTcamTcamMem_t)/3)) ? 0 : \
                (end_idx <= (TABLE_MAX_INDEX(lchip, LpmTcamTcamMem_t)/3*2)) ? 1 : 2;
            break;
        default:
            break;
    }


    for (index = start_idx; index < end_idx; index+= (p_param->step*req_num))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"Do MEM-BIST type [%u] index[%u]\n", p_param->type, index);
        wrapper_index = (wrapper&0x01) ? (index-1) : (index+1);

        p_param->req_num = (((end_idx-index-1+p_param->step)/p_param->step) < (req_num))? \
            ((end_idx-index-1+p_param->step)/p_param->step) : req_num;

        {
            _sys_tm_diag_bist_trigger_write_control_wrapper(lchip, p_param->type,
                                                                    p_param->pattern,
                                                                    wrapper_index,
                                                                    p_param->step,
                                                                    0,
                                                                    p_param->req_num);
        }
        _sys_tm_diag_bist_trigger(lchip, p_param->type, 0, ext_data);
        _sys_tm_diag_bist_trigger(lchip, p_param->type, 1, ext_data);
        _sys_tm_diag_bist_done(lchip, p_param->type, ext_data);

        /*excp hit index*/
        excp_index = (wrapper&0x01) ? (index-1) : index;

        p_param->index = excp_index;
        if(_sys_tm_diag_bist_check_result(lchip, p_param, p_result))
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"Test index[%u] error, pattern[%u], round [%u]\n", index, p_param->pattern, p_param->round);
        }

        /*clear control wrapper valid entry*/
        _sys_tm_diag_bist_trigger_write_control_wrapper(lchip, p_param->type,
                                                                p_param->pattern,
                                                                wrapper_index,
                                                                p_param->step,
                                                                1,
                                                                p_param->req_num);
    }
    return ret;
}

int32
_sys_tm_diag_tcam_function_bist(uint8 lchip, uint8 mem_type, uint8 test_pattern,
                                                           uint8 mem_id,
                                                           uint16* err_entry_cnt,
                                                            sys_diag_tcam_bmp* p_bmp)
{
    int32 ret = CTC_E_NONE;
    uint8 wrapper;
    uint8 round ;
    uint8 step ;
    uint8 shift_times;
    uint16 start_index;
    uint16 end_index;
    uint32 ext_data;
    tcam_bist_param_t bist_param;
    tcam_bist_result_t bist_result;

    bist_result.err_entry_cnt = err_entry_cnt;
    bist_result.p_bmp = p_bmp;

    switch (mem_type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            step = 4;
            start_index = (mem_id-DRV_FTM_TCAM_KEY0)*SYS_USW_DIAG_BIST_FLOW_RAM_SZ;
            end_index = (mem_id-DRV_FTM_TCAM_KEY0)*SYS_USW_DIAG_BIST_FLOW_RAM_SZ + (((mem_id-DRV_FTM_TCAM_KEY0) <= 14) ? 1024: SYS_USW_DIAG_BIST_FLOW_RAM_SZ);
            ext_data = (mem_id-DRV_FTM_TCAM_KEY0);
            shift_times = 80;
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            step = 4;
            shift_times = 46;
            {
                if(mem_id < DRV_FTM_LPM_TCAM_KEY4)
                {
                    start_index = (mem_id-DRV_FTM_LPM_TCAM_KEY0)*1024;
                    end_index = start_index + 1024;
                    ext_data = 0;
                }
                else if(mem_id < DRV_FTM_LPM_TCAM_KEY8)
                {
                    start_index = 8192+(mem_id-DRV_FTM_LPM_TCAM_KEY4)*1024;
                    end_index = start_index + 1024;
                    ext_data = 1;
                }
                else
                {
                    start_index = 16384 + (mem_id-DRV_FTM_LPM_TCAM_KEY8)*2048;
                    end_index = start_index+2048;
                    ext_data = 2;
                }
            }
            break;
        default:
            return CTC_E_NONE;
    }

    bist_param.lpm_id= ext_data & 0xF;
    for(wrapper=0; wrapper < 4; wrapper++)
    {
        CTC_ERROR_RETURN(_sys_tm_diag_bist_tcam_prepare(lchip, mem_type,
                            test_pattern,
                            start_index,
                            end_index,
                            step));


        /*test N round for one pattern*/
        for(round=0; round < sys_usw_diag_req_key[test_pattern].req_key_num; round++)
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Test pattern [%u]!!!!!\n", test_pattern);
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Test wrapper [%u]!!!!!\n", wrapper);
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Test round [%u]!!!!!\n", round);

            bist_param.type = mem_type;
            bist_param.pattern = test_pattern;
            bist_param.round = round;
            bist_param.step = step;
            if(sys_usw_diag_req_key[test_pattern].shift_en)
            {
                uint8 shift = 0;
                uint16 tmp_error_index = 0xFFFF;
                for(shift=0; shift < shift_times; shift++)
                {
                    bist_param.req_num = 1;
                    /*1. write lookup key*/
                    CTC_ERROR_RETURN(_sys_tm_diag_bist_req_prepare(lchip, mem_type, wrapper, test_pattern, round,shift, 0));

                    /*2. trigger bist and get the first error index*/
                    _sys_tm_diag_bist_trigger(lchip, mem_type, 0, ext_data);
                    _sys_tm_diag_bist_trigger(lchip, mem_type, 1, ext_data);
                    _sys_tm_diag_bist_done(lchip, mem_type, ext_data);

                    /*3. check result*/
                    bist_result.first_err_idx = 0xFFFF;
                    if(CTC_E_NONE == _sys_tm_diag_bist_check_result(lchip, &bist_param, &bist_result))
                    {
                        continue;
                    }

                    /*4. if error, delete this entry, then trigger once*/
                    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"First error index[%u] error, pattern[%u], round [%u], shift[%u]\n", bist_result.first_err_idx, test_pattern, round, shift);
                    do
                    {
                        tmp_error_index = bist_result.first_err_idx;
                        /*delete this entry*/
                        _sys_tm_diag_bist_mem_delete(lchip, mem_type, tmp_error_index, tmp_error_index+1);

                        /*trigger once*/
                        _sys_tm_diag_bist_trigger(lchip, mem_type, 0, ext_data);
                        _sys_tm_diag_bist_trigger(lchip, mem_type, 1, ext_data);
                        _sys_tm_diag_bist_done(lchip, mem_type, ext_data);

                        bist_result.first_err_idx = 0xFFFF;
                        ret = _sys_tm_diag_bist_check_result(lchip, &bist_param, &bist_result);
                        if(ret && bist_result.first_err_idx == tmp_error_index)
                        {
                            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "match the invalid index, this block can not be used anymore, error index[%u], bit[%u]\n", bist_result.first_err_idx, shift);
                            ret = CTC_E_HW_FAIL;
                            break;
                        }
                    }while(ret != CTC_E_NONE);
                    if(ret == CTC_E_HW_FAIL)
                    {
                        break;
                    }
                }
            }
            else
            {
                CTC_ERROR_RETURN(_sys_tm_diag_bist_req_prepare(lchip, mem_type, wrapper, test_pattern, round, 0, 1));
                CTC_ERROR_RETURN(_sys_tm_diag_bist_cmp_and_result(lchip,
                                start_index,
                                end_index,
                                wrapper,
                                &bist_param,
                                &bist_result));
            }
            if(ret == CTC_E_HW_FAIL)
            {
                break;
            }

        }

        /*delete tcam entry*/
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip, mem_type);
        /*always clear bist enable after bist is done*/
        _sys_tm_diag_bist_trigger(lchip, mem_type, 0, ext_data);

        if(ret == CTC_E_HW_FAIL)
        {
            break;
        }
        start_index += 1;
    }
    return ret;
}
struct sys_usw_diag_tcam_mbist_map_e
{
    uint8 busy_field_id;
    uint8 pass_field_id;
    uint16 mem_id;
};
typedef struct sys_usw_diag_tcam_mbist_map_e sys_usw_diag_tcam_mbist_map_t;

sys_usw_diag_tcam_mbist_map_t flow_tcam_map[] = {
    {FlowTcamMBistCtl_userId0TcamMBistBusy_f, FlowTcamMBistCtl_userId0TcamMBistPass_f, DRV_FTM_TCAM_KEY0},
    {FlowTcamMBistCtl_userId1TcamMBistBusy_f, FlowTcamMBistCtl_userId1TcamMBistPass_f, DRV_FTM_TCAM_KEY1},
    {FlowTcamMBistCtl_userId2TcamMBistBusy_f, FlowTcamMBistCtl_userId2TcamMBistPass_f, DRV_FTM_TCAM_KEY2},
    {FlowTcamMBistCtl_userId3TcamMBistBusy_f, FlowTcamMBistCtl_userId3TcamMBistPass_f, DRV_FTM_TCAM_KEY3},

    {FlowTcamMBistCtl_ipeAcl0TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl0TcamMBistPass_f, DRV_FTM_TCAM_KEY4},
    {FlowTcamMBistCtl_ipeAcl1TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl1TcamMBistPass_f, DRV_FTM_TCAM_KEY5},
    {FlowTcamMBistCtl_ipeAcl2TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl2TcamMBistPass_f, DRV_FTM_TCAM_KEY6},
    {FlowTcamMBistCtl_ipeAcl3TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl3TcamMBistPass_f, DRV_FTM_TCAM_KEY7},
    {FlowTcamMBistCtl_ipeAcl4TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl4TcamMBistPass_f, DRV_FTM_TCAM_KEY8},
    {FlowTcamMBistCtl_ipeAcl5TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl5TcamMBistPass_f, DRV_FTM_TCAM_KEY9},
    {FlowTcamMBistCtl_ipeAcl6TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl6TcamMBistPass_f, DRV_FTM_TCAM_KEY10},
    {FlowTcamMBistCtl_ipeAcl7TcamMBistBusy_f, FlowTcamMBistCtl_ipeAcl7TcamMBistPass_f, DRV_FTM_TCAM_KEY11},

    {FlowTcamMBistCtl_epeAcl0TcamMBistBusy_f, FlowTcamMBistCtl_epeAcl0TcamMBistPass_f, DRV_FTM_TCAM_KEY12},
    {FlowTcamMBistCtl_epeAcl1TcamMBistBusy_f, FlowTcamMBistCtl_epeAcl1TcamMBistPass_f, DRV_FTM_TCAM_KEY13},
    {FlowTcamMBistCtl_epeAcl2TcamMBistBusy_f, FlowTcamMBistCtl_epeAcl2TcamMBistPass_f, DRV_FTM_TCAM_KEY14},

    {FlowTcamMBistCtl_share0TcamMBistBusy_f, FlowTcamMBistCtl_share0TcamMBistPass_f, DRV_FTM_TCAM_KEY15},
    {FlowTcamMBistCtl_share1TcamMBistBusy_f, FlowTcamMBistCtl_share1TcamMBistPass_f, DRV_FTM_TCAM_KEY16},
    {FlowTcamMBistCtl_share2TcamMBistBusy_f, FlowTcamMBistCtl_share2TcamMBistPass_f, DRV_FTM_TCAM_KEY17},
    {FlowTcamMBistCtl_share3TcamMBistBusy_f, FlowTcamMBistCtl_share3TcamMBistPass_f, DRV_FTM_TCAM_KEY18}
};

sys_usw_diag_tcam_mbist_map_t cid_tcam_map[] = {
    {IpeAclCidTcamMBistCtl_tcamWrapperMBistBusy_f, IpeAclCidTcamMBistCtl_tcamWrapperMBistPass_f, DRV_FTM_CID_TCAM},
};

sys_usw_diag_tcam_mbist_map_t lpm_tcam_map[] = {
    {LpmTcamMBistCtl_tcamRpf0MBistBusy_f, LpmTcamMBistCtl_tcamRpf0MBistPass_f, DRV_FTM_LPM_TCAM_KEY0},
    {LpmTcamMBistCtl_tcamRpf1MBistBusy_f, LpmTcamMBistCtl_tcamRpf1MBistPass_f, DRV_FTM_LPM_TCAM_KEY4},
    {LpmTcamMBistCtl_tcamShareMBistBusy_f, LpmTcamMBistCtl_tcamShareMBistPass_f, DRV_FTM_LPM_TCAM_KEY8}
};

sys_usw_diag_tcam_mbist_map_t enqueue_tcam_map[] = {
    {QMgrEnqTcamMBistCtl_tcamWrapperMBistBusy_f, QMgrEnqTcamMBistCtl_tcamWrapperMBistPass_f, DRV_FTM_QUEUE_TCAM},
};
uint8
_sys_usw_diag_tcam_mbist_done(uint8 lchip, uint8 mem_type, uint32* ds)
{
    uint16 loop = 0;
    uint16 loop_max;
    uint32 table_id;
    sys_usw_diag_tcam_mbist_map_t* p_map;

    if(mem_type == SYS_USW_DIAG_BIST_FLOW_TCAM)
    {
        p_map = flow_tcam_map;
        loop_max = sizeof(flow_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = FlowTcamMBistCtl_t;
    }
    else if(mem_type == SYS_USW_DIAG_BIST_LPM_TCAM)
    {
        p_map = lpm_tcam_map;
        loop_max = sizeof(lpm_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = LpmTcamMBistCtl_t;
    }
    else if(mem_type == SYS_USW_DIAG_BIST_CID_TCAM)
    {
        p_map = cid_tcam_map;
        loop_max = sizeof(cid_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = IpeAclCidTcamMBistCtl_t;

    }
    else
    {
        p_map = enqueue_tcam_map;
        loop_max = sizeof(enqueue_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = QMgrEnqTcamMBistCtl_t;
    }
    for(loop=0; loop < loop_max; loop++)
    {
        if(DRV_GET_FIELD_V(lchip, table_id, p_map[loop].busy_field_id, ds))
        {
            return 0;
        }
    }

    return 1;
}
#ifndef CTC_SHELL_DEBUG_ON
int32
sys_usw_diag_output(
                            char* op,
                            sal_systime_t* tv1,
                            sal_systime_t* tv2)
{
    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s\n", op);
    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "START TIME:[%10u s:%3u us]\n", tv1->tv_sec, tv1->tv_usec);
    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "END   TIME:[%10u s:%3u us]\n", tv2->tv_sec, tv2->tv_usec);
    if(tv2->tv_usec >= tv1->tv_usec)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "USED  TIME:[%10u s:%3u us]\n", tv2->tv_sec - tv1->tv_sec, (tv2->tv_usec - tv1->tv_usec));
    }
    else
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "USED  TIME:[%10u s:%3u us]\n", tv2->tv_sec - tv1->tv_sec - 1, (tv2->tv_usec + 1000000 - tv1->tv_usec));
    }
    return 0;
}
#endif
int32
_sys_usw_diag_bist_flow_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[12] = {0xff,0,0,
                      0xff,0,0,
                      0xff,0,0,
                      0xff,0,0};
    uint8  loop = 0;
    FlowTcamBistReqFA_m  flow_tcam_req;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_FLOW_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&flow_tcam_req, 0 , sizeof(FlowTcamBistReqFA_m));
        SetFlowTcamBistReqFA(V,bistReqKeyEnd_f,   &flow_tcam_req, 1);
        SetFlowTcamBistReqFA(A, bistReqKey_f, &flow_tcam_req, buf);
        SetFlowTcamBistReqFA(V,bistReqKeySize_f,  &flow_tcam_req, 0);
        SetFlowTcamBistReqFA(V,bistReqKeyValid_f, &flow_tcam_req, 1);
        cmd = DRV_IOW(FlowTcamBistReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &flow_tcam_req);
    }
    return CTC_E_NONE;
}
int32
_sys_usw_diag_bist_lpm_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[8] =  {0xff,0,
                      0xff,0,
                      0xff,0,
                      0xff,0};
    uint8  loop = 0;
    LpmTcamBistReq0FA_m  lpm_tcam_req;
    sal_memset(&lpm_tcam_req, 0 , sizeof(LpmTcamBistReq0FA_m));
    for (loop = 0; loop < SYS_USW_DIAG_BIST_LPM_REQ_MEM; loop++)
    {
        if(DRV_FROM_TMM(lchip))
        {
            buf[0] = 0xff - loop;
            buf[1] = (0xff - loop) << 14;
            buf[2] = ((0xff - loop) & 0x0F) << 28;
            buf[3] = ((0xff - loop) & 0xF0) >> 4;
            buf[4] = (0xff - loop) << 10;
        }
        else
        {
            buf[0] = 0xff - loop;
            buf[2] = 0xff - loop;
            buf[4] = 0xff - loop;
            buf[6] = 0xff - loop;
        }

        sal_memcpy(&lpm_tcam_req, buf,  sizeof(uint32)*8);/*184bits = 4*8byte,rtl auto align */

        SetLpmTcamBistReq0FA(V,bistReqKeySize_f,  &lpm_tcam_req, 0);
        SetLpmTcamBistReq0FA(V,bistReqKeyValid_f, &lpm_tcam_req, 1);
        cmd = DRV_IOW(LpmTcamBistReq0FA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &lpm_tcam_req);

        cmd = DRV_IOW(LpmTcamBistReq1FA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &lpm_tcam_req);

        cmd = DRV_IOW(LpmTcamBistReq2FA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &lpm_tcam_req);
    }
    return CTC_E_NONE;
}
int32
_sys_tm_diag_bist_trigger_write_control_wrapper(uint8 lchip, sys_usw_diag_bist_tcam_t type,
                                                            uint8  test_pattern,
                                                            uint32 index,
                                                            uint8  step,
                                                            uint8 is_clear,
                                                            uint8 req_num)
{
    uint32  ds[7];
    uint8 loop;
    uint32 address;
    uint32 base;
    switch (type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            ds[3] = 0xFFFFFFFF;
            ds[4] = 0xFFFFFFFF;
            ds[5] = 0x0000FFFF;
            base = SYS_USW_DIAG_FLOW_TCAM_ADDR(lchip);
            for (loop = 0; loop < req_num; loop++)
            {
                ds[0] = (0x5A5A5A<<8)|(loop<<1);
                ds[1] = 0x5A5A5A5A;
                ds[2] = 0x5A5A;
                ds[6] = is_clear?0:0x80000000;
                address = (base + (index+loop*step)*32);
                drv_usw_chip_write_sram_entry(lchip, address, ds, 28);
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            ds[2] = 0xFFFFFFFF;
            ds[3] = 0x3FFF;
            base = SYS_USW_DIAG_LPM_TCAM_ADDR(lchip);
            for (loop = 0; loop < req_num; loop++)
            {
                ds[0] = (0x5A5A5A<<8)|(loop<<1);
                ds[1] = 0x1A5A;
                ds[3] = is_clear?0:(ds[3]|0x80000000);
                address = (base + (index+loop*step)*16);
                drv_usw_chip_write_sram_entry(lchip, address, ds, 16);
            }
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_diag_tcam_mbist_check_result(uint8 lchip, uint8 mem_type, uint32* ds, uint8* err_mem_id, uint8* err_cnt)
{
    uint16 loop = 0;
    uint16 loop_max;
    uint32 table_id;
    sys_usw_diag_tcam_mbist_map_t* p_map;
    if(mem_type == SYS_USW_DIAG_BIST_FLOW_TCAM)
    {
        p_map = flow_tcam_map;
        loop_max = sizeof(flow_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = FlowTcamMBistCtl_t;
    }
    else if(mem_type == SYS_USW_DIAG_BIST_LPM_TCAM)
    {
        p_map = lpm_tcam_map;
        loop_max = sizeof(lpm_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = LpmTcamMBistCtl_t;
    }
    else if(mem_type == SYS_USW_DIAG_BIST_CID_TCAM)
    {
        p_map = cid_tcam_map;
        loop_max = sizeof(cid_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = IpeAclCidTcamMBistCtl_t;

    }
    else
    {
        p_map = enqueue_tcam_map;
        loop_max = sizeof(enqueue_tcam_map)/sizeof(sys_usw_diag_tcam_mbist_map_t);
        table_id = QMgrEnqTcamMBistCtl_t;
    }
    for(loop=0; loop < loop_max; loop++)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Do tcam mbist, mem_type[%u], memory_block[%u]\n", mem_type, loop);
        if(0 == DRV_GET_FIELD_V(lchip, table_id, p_map[loop].pass_field_id, ds))
        {
            err_mem_id[(*err_cnt)++] = p_map[loop].mem_id;
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mem_type %u mbist fail, memory id is %u\n", mem_type, p_map[loop].mem_id);
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_tcam_mbist(uint8 lchip, uint8 mem_type, uint8* err_mem_array, uint8* err_cnt)
{
    int32 ret;
    uint32 cmd;
    ds_t ds;
    uint8 mbist_done = 0;
    uint32 wait_cnt = 0;
    uint32 table_id;
    uint32 field_id_start;
    uint32 field_id_reset;
    uint32 reset_table_id;

    if(mem_type == SYS_USW_DIAG_BIST_FLOW_TCAM)
    {
        table_id = FlowTcamMBistCtl_t;
        field_id_start = FlowTcamMBistCtl_tcamMBistStart_f;
        field_id_reset = FlowTcamMBistCtl_tcamMBistRst_f;
        reset_table_id = FlowTcamTcamVaidBitReset_t;
    }
    else if(mem_type == SYS_USW_DIAG_BIST_LPM_TCAM)
    {
        table_id = LpmTcamMBistCtl_t;
        field_id_start = LpmTcamMBistCtl_tcamMBistStart_f;
        field_id_reset = LpmTcamMBistCtl_tcamMBistRst_f;
        reset_table_id = LpmTcamTcamVaidBitReset_t;
    }
    else if(mem_type == SYS_USW_DIAG_BIST_CID_TCAM)
    {
        table_id = IpeAclCidTcamMBistCtl_t;
        field_id_start = IpeAclCidTcamMBistCtl_tcamWrapperMBistStart_f;
        field_id_reset = IpeAclCidTcamMBistCtl_tcamWrapperMBistRst_f;
        reset_table_id = IpeAclTcamValidBitReset_t;

    }
    else
    {
        table_id = QMgrEnqTcamMBistCtl_t;
        field_id_start = QMgrEnqTcamMBistCtl_tcamWrapperMBistStart_f;
        field_id_reset = QMgrEnqTcamMBistCtl_tcamWrapperMBistRst_f;
        reset_table_id = QMgrEnqTcamValidBitReset_t;
    }
    /*1. trigger mbist*/
    sal_memset(ds, 0, sizeof(ds));
    cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(ds, 0, sizeof(ds));
    DRV_SET_FIELD_V(lchip, table_id, field_id_reset, &ds, 1);
    cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    DRV_SET_FIELD_V(lchip, table_id, field_id_reset, &ds, 1);
    DRV_SET_FIELD_V(lchip, table_id, field_id_start, &ds, 1);
    cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    /*2. wait mbist done*/
    cmd = DRV_IOR(table_id, DRV_ENTRY_FLAG);
    do
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        mbist_done = _sys_usw_diag_tcam_mbist_done(lchip, mem_type, ds);
        wait_cnt++;
    }while(!mbist_done && wait_cnt < 2000);
    if(0 == mbist_done)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mem_type %u mbist hw busy\n", mem_type);
        return CTC_E_HW_BUSY;
    }

    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    /*3. check mbist result*/
    ret = _sys_usw_diag_tcam_mbist_check_result(lchip, mem_type, ds, err_mem_array, err_cnt);

    /*4. reset mbist and set tcam to default*/
    sal_memset(ds, 0, sizeof(ds));
    cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &ds);

    /*5. reset tcam valid bits */
    wait_cnt = 1;
    cmd = DRV_IOW(reset_table_id, 0);
    DRV_IOCTL(lchip, 0, cmd, &wait_cnt);

    wait_cnt = 0;
    cmd = DRV_IOW(reset_table_id, 0);
    DRV_IOCTL(lchip, 0, cmd, &wait_cnt);
    return ret;
}

int32
_sys_usw_diag_bist_tcam_prepare(uint8 lchip, sys_usw_diag_bist_tcam_t type,uint8 is_clear)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 i   = 0;
    uint32 j   = 0;
    uint32 buf[10] = {0};
    uint32 table_id=0;

    uint32 reqmem_cnt=0;
    uint32 cpuWrData_field_id = 0;
    uint32 cpuWrMask_field_id = 0;
    uint32 tcamEntryValid_field_id = 0;
    ds_t  ds;

    switch (type)
    {
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM:
            {
                table_id = ProgramIngAclTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM;
                cpuWrData_field_id = ProgramIngAclTcamMem_data_f;
                cpuWrMask_field_id = ProgramIngAclTcamMem_mask_f;
                tcamEntryValid_field_id = ProgramIngAclTcamMem_valid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM:
            {
                table_id = ProgramEgrAclTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM;
                cpuWrData_field_id = ProgramEgrAclTcamMem_data_f;
                cpuWrMask_field_id = ProgramEgrAclTcamMem_mask_f;
                tcamEntryValid_field_id = ProgramEgrAclTcamMem_valid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM:
            {
                table_id = DsEgrLtidSelectTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_REQ_MEM;
                cpuWrData_field_id = DsEgrLtidSelectTcamMem_data_f;
                cpuWrMask_field_id = DsEgrLtidSelectTcamMem_mask_f;
                tcamEntryValid_field_id = DsEgrLtidSelectTcamMem_valid_f;
            }
            break;

        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            {
                table_id = FlowTcamTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_FLOW_REQ_MEM;
                cpuWrData_field_id = FlowTcamTcamMem_cpuWrData_f;
                cpuWrMask_field_id = FlowTcamTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = FlowTcamTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            {
                table_id = LpmTcamTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_LPM_REQ_MEM;
                cpuWrData_field_id = LpmTcamTcamMem_cpuWrData_f;
                cpuWrMask_field_id = LpmTcamTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = LpmTcamTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_CID_TCAM:
            {
                table_id = IpeCidTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_CID_REQ_MEM;
                cpuWrData_field_id = IpeCidTcamMem_cpuWrData_f;
                cpuWrMask_field_id = IpeCidTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = IpeCidTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_ENQUEUE_TCAM:
             {
                table_id = QMgrEnqTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM;
                cpuWrData_field_id = QMgrEnqTcamMem_cpuWrData_f;
                cpuWrMask_field_id = QMgrEnqTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = QMgrEnqTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM:
        case SYS_USW_DIAG_BIST_TIDSELECT_TCAM:
            {
                table_id = DsLtidSelectTcamMem_t;
                reqmem_cnt = DRV_FROM_AT(lchip) ? SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_REQ_MEM:SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM;
                cpuWrData_field_id = DsLtidSelectTcamMem_data_f;
                cpuWrMask_field_id = DsLtidSelectTcamMem_mask_f;
                tcamEntryValid_field_id = DsLtidSelectTcamMem_valid_f;
            }
            break;

        case SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM:
            {
              table_id =  EgrSclHashTcamMem_t;
              reqmem_cnt = SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM;
              cpuWrData_field_id = EgrSclHashTcamMem_cpuWrData_f;
              cpuWrMask_field_id = EgrSclHashTcamMem_cpuWrMask_f;
              tcamEntryValid_field_id = EgrSclHashTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_EGRACL_TCAM:
            {
                table_id =  EgressAclTcamTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_EGRACL_REQ_MEM;
                cpuWrData_field_id = EgressAclTcamTcamMem_cpuWrData_f;
                cpuWrMask_field_id = EgressAclTcamTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = EgressAclTcamTcamMem_tcamEntryValid_f;
            }
            break;

        case SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM:
            {
                table_id =  IpeHdrAdjRouterMacTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM;
                cpuWrData_field_id = IpeHdrAdjRouterMacTcamMem_cpuWrData_f;
                cpuWrMask_field_id = IpeHdrAdjRouterMacTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = IpeHdrAdjRouterMacTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM:
            {
                table_id = IpeHdrAdjUdfTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM;
                cpuWrData_field_id = IpeHdrAdjUdfTcamMem_cpuWrData_f;
                cpuWrMask_field_id = IpeHdrAdjUdfTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = IpeHdrAdjUdfTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_PROGRAMACL_TCAM:
            {
                table_id = ProgramAclTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM;
                cpuWrData_field_id = ProgramAclTcamMem_data_f;
                cpuWrMask_field_id = ProgramAclTcamMem_mask_f;
                tcamEntryValid_field_id = ProgramAclTcamMem_valid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_USERIDHASH_TCAM:
            {
                table_id = UserIdHashTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM;
                cpuWrData_field_id = UserIdHashTcamMem_cpuWrData_f;
                cpuWrMask_field_id = UserIdHashTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = UserIdHashTcamMem_tcamEntryValid_f;
            }
            break;
        case SYS_USW_DIAG_BIST_USERID_TCAM:
            {
                table_id = UserIdTcamMem_t;
                reqmem_cnt = SYS_USW_DIAG_BIST_USERID_REQ_MEM;
                cpuWrData_field_id = UserIdTcamMem_cpuWrData_f;
                cpuWrMask_field_id = UserIdTcamMem_cpuWrMask_f;
                tcamEntryValid_field_id = UserIdTcamMem_tcamEntryValid_f;
            }
            break;
        default:
            break;
    }
    sal_memset(&ds, 0,sizeof(ds));
    reqmem_cnt = reqmem_cnt ? reqmem_cnt : 1;
    for (i = 0; i <DRV_TABLE_MAX_INDEX(lchip, table_id); i++)
    {
        j = i % reqmem_cnt;
        buf[0] = 0xff-j;
        DRV_SET_FIELD_A(lchip, table_id, cpuWrData_field_id, ds, buf);
        buf[0] = 0xff;
        DRV_SET_FIELD_A(lchip, table_id, cpuWrMask_field_id, ds, buf);
        DRV_SET_FIELD_V(lchip, table_id, tcamEntryValid_field_id, ds, is_clear?0:1);

        cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
   }
    return ret;
}


int32
_sys_usw_diag_bist_egracl_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[20] = {0};
    uint8  loop = 0;

    EgressAclTcamBistReqFa_m  egracl_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGRACL_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        buf[5]= 0xff-loop;
        buf[10]= 0xff-loop;
        buf[15]= 0xff-loop;
        sal_memset(&egracl_tcam_req, 0 , sizeof(EgressAclTcamBistReqFa_m));
        SetEgressAclTcamBistReqFa(A, bistReqKey_f, &egracl_tcam_req, buf);
        SetEgressAclTcamBistReqFa(V,bistReqKeyValid_f, &egracl_tcam_req, 1);
        SetEgressAclTcamBistReqFa(V,bistReqKeySize_f, &egracl_tcam_req, 1);
        cmd = DRV_IOW(EgressAclTcamBistReqFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &egracl_tcam_req);
    }
    return CTC_E_NONE;
}

int32 
_sys_usw_diag_bist_igs_programacl_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[5] = {0, 0, 0, 0 };
    uint8  loop = 0;

    ProgramIngAclTcamBist0ReqFA_m  programacl_igs_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&programacl_igs_tcam_req, 0 , sizeof(ProgramIngAclTcamBist0ReqFA_m));
        SetProgramIngAclTcamBist0ReqFA(A, key_f, &programacl_igs_tcam_req, buf);
        SetProgramIngAclTcamBist0ReqFA(V,keyValid_f, &programacl_igs_tcam_req, 1);
        SetProgramIngAclTcamBist0ReqFA(V,keySize_f, &programacl_igs_tcam_req, 0);
        cmd = DRV_IOW(ProgramIngAclTcamBist0ReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &programacl_igs_tcam_req);
    }
    return CTC_E_NONE;
}

int32 
_sys_usw_diag_bist_egs_programacl_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[5] = {0, 0, 0, 0 };
    uint8  loop = 0;

    ProgramEgrAclTcamBist0ReqFA_m  programacl_egs_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&programacl_egs_tcam_req, 0 , sizeof(ProgramEgrAclTcamBist0ReqFA_m));
        SetProgramEgrAclTcamBist0ReqFA(A, key_f, &programacl_egs_tcam_req, buf);
        SetProgramEgrAclTcamBist0ReqFA(V,keyValid_f, &programacl_egs_tcam_req, 1);
        SetProgramEgrAclTcamBist0ReqFA(V,keySize_f, &programacl_egs_tcam_req, 0);
        cmd = DRV_IOW(ProgramEgrAclTcamBist0ReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &programacl_egs_tcam_req);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_bist_egs_program_tcam_ltid_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[5] = {0, 0, 0, 0,0};
    uint8  loop = 0;

    ProgramEgrAclLtidTcamBistReqFA_m  tidselect_egs_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&tidselect_egs_tcam_req, 0 , sizeof(ProgramEgrAclLtidTcamBistReqFA_m));
        SetProgramEgrAclLtidTcamBistReqFA(A, key_f, &tidselect_egs_tcam_req, buf);
        SetProgramEgrAclLtidTcamBistReqFA(V,keyValid_f, &tidselect_egs_tcam_req, 1);
        cmd = DRV_IOW(ProgramEgrAclLtidTcamBistReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &tidselect_egs_tcam_req);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_bist_igs_program_tcam_ltid_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[5] = {0, 0, 0, 0,0};
    uint8  loop = 0;
    ProgramIngAclLtidTcamBistReqFA_m  tidselect_igs_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&tidselect_igs_tcam_req, 0 , sizeof(ProgramIngAclLtidTcamBistReqFA_m));
        SetProgramIngAclLtidTcamBistReqFA(A, key_f, &tidselect_igs_tcam_req, buf);
        SetProgramIngAclLtidTcamBistReqFA(V,keyValid_f, &tidselect_igs_tcam_req, 1);
        cmd = DRV_IOW(ProgramIngAclLtidTcamBistReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &tidselect_igs_tcam_req);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_bist_userid_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[20] = {0};
    uint8  loop = 0;

    UserIdTcamBistReqFa_m  userid_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_USERID_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        buf[5] = 0xff - loop;
        buf[10] = 0xff - loop;
        buf[15] = 0xff - loop;
        sal_memset(&userid_tcam_req, 0 , sizeof(UserIdTcamBistReqFa_m));
        SetUserIdTcamBistReqFa(A, bistReqKey_f, &userid_tcam_req, buf);
        SetUserIdTcamBistReqFa(V,bistReqKeyValid_f, &userid_tcam_req, 1);
        SetUserIdTcamBistReqFa(V,bistReqKeySize_f, &userid_tcam_req, 1);
        cmd = DRV_IOW(UserIdTcamBistReqFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &userid_tcam_req);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_bist_useridhash_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[11] = {0};
    uint8  loop = 0;

    UserIdHashTcamBistReqFa_m  useridhash_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM; loop++)
    {
        if (DRV_FROM_AT(lchip))
        {
            buf[0] = 0xff - loop;
            buf[2] = (0xff - loop)<<24;
            buf[5] = (0xff - loop)<<16;
            buf[8] = (0xff - loop)<<8;
        }
        else
        {
            buf[0] = 0xff - loop;
            buf[2] = (0xff - loop)<<21;
            buf[5] = (0xff - loop)<<10;
            buf[7] = ((0xff - loop)&0x1)<<31;
            buf[8] = ((0xff - loop)>>1);
        }

        sal_memset(&useridhash_tcam_req, 0 ,sizeof(UserIdHashTcamBistReqFa_m));
        SetUserIdHashTcamBistReqFa(A, bistReqKey_f, &useridhash_tcam_req, buf);
        SetUserIdHashTcamBistReqFa(V,bistReqKeyValid_f, &useridhash_tcam_req, 1);
        cmd = DRV_IOW(UserIdHashTcamBistReqFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &useridhash_tcam_req);
    }
    return CTC_E_NONE;
}


int32
_sys_usw_diag_bist_programacl_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[5] = {0, 0, 0, 0 };
    uint8  loop = 0;

    ProgramAclTcamBist0ReqFA_m  programacl_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&programacl_tcam_req, 0 , sizeof(ProgramAclTcamBist0ReqFA_m));
        SetProgramAclTcamBist0ReqFA(A, key_f, &programacl_tcam_req, buf);
        SetProgramAclTcamBist0ReqFA(V,keyValid_f, &programacl_tcam_req, 1);
        SetProgramAclTcamBist0ReqFA(V,keySize_f, &programacl_tcam_req, 0);
        cmd = DRV_IOW(ProgramAclTcamBist0ReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &programacl_tcam_req);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_bist_ipehdrudf_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[4] = {0, 0, 0, 0 };
    uint8  loop = 0;

    IpeHdrAdjUdfTcamBistReqFa_m  IpeHdrAdjUdf_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&IpeHdrAdjUdf_tcam_req, 0 , sizeof(IpeHdrAdjUdfTcamBistReqFa_m));
        SetIpeHdrAdjUdfTcamBistReqFa(A, bistReqKey_f, &IpeHdrAdjUdf_tcam_req, buf);
        SetIpeHdrAdjUdfTcamBistReqFa(V,bistReqKeyValid_f, &IpeHdrAdjUdf_tcam_req, 1);
        cmd = DRV_IOW(IpeHdrAdjUdfTcamBistReqFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &IpeHdrAdjUdf_tcam_req);
    }
    return CTC_E_NONE;
}


int32
_sys_usw_diag_bist_ipehdradjrmac_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[4] = {0, 0, 0, 0 };
    uint8  loop = 0;

    IpeHdrAdjRouterMacTcamBistReqFa_m  ipehdradjrmac_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&ipehdradjrmac_tcam_req, 0 , sizeof(IpeHdrAdjRouterMacTcamBistReqFa_m));
        SetIpeHdrAdjRouterMacTcamBistReqFa(A,bistReqKey_f, &ipehdradjrmac_tcam_req, buf);
        SetIpeHdrAdjRouterMacTcamBistReqFa(V,bistReqKeyValid_f, &ipehdradjrmac_tcam_req, 1);
        cmd = DRV_IOW(IpeHdrAdjRouterMacTcamBistReqFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ipehdradjrmac_tcam_req);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_diag_bist_LtidSelect_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[4] = {0, 0, 0, 0 };
    uint8  loop = 0;

    ProgramLtidTcamBistReqFA_m  tidselect_tcam_req;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&tidselect_tcam_req, 0 , sizeof(ProgramLtidTcamBistReqFA_m));
        SetProgramLtidTcamBistReqFA(A, key_f, &tidselect_tcam_req, buf);
        SetProgramLtidTcamBistReqFA(V,keyValid_f, &tidselect_tcam_req, 1);
        cmd = DRV_IOW(ProgramLtidTcamBistReqFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &tidselect_tcam_req);
    }
    return CTC_E_NONE;
}


int32
_sys_usw_diag_bist_egrsclhash_tcam_req_prepare(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 buf[3] = {0, 0 ,0};
    uint8  loop = 0;

    EgrSclHashTcamBistReqFa_m  egrsclhash_tcam_req;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&egrsclhash_tcam_req, 0 , sizeof(EgrSclHashTcamBistReqFa_m));
        SetEgrSclHashTcamBistReqFa(A,bistReqKey_f, &egrsclhash_tcam_req, buf);
        SetEgrSclHashTcamBistReqFa(V,bistReqKeySize_f, &egrsclhash_tcam_req, 0);
        SetEgrSclHashTcamBistReqFa(V,bistReqKeyValid_f, &egrsclhash_tcam_req, 1);
        cmd = DRV_IOW(EgrSclHashTcamBistReqFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &egrsclhash_tcam_req);
    }
    return CTC_E_NONE;
}


int32
_sys_usw_diag_bist_cid_tcam_req_prepare(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 buf = 0xff;
    uint8  loop = 0;
    IpeCidTcamBistReq_m  cid_tcam_req;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_CID_REQ_MEM; loop++)
    {
        buf = 0xff - loop;
        sal_memset(&cid_tcam_req, 0 , sizeof(IpeCidTcamBistReq_m));
        sal_memcpy(&cid_tcam_req, &buf, 3);
        SetIpeCidTcamBistReq(V,keySize_f,  &cid_tcam_req, 0);
        SetIpeCidTcamBistReq(V,valid_f, &cid_tcam_req, 1);
        cmd = DRV_IOW(IpeCidTcamBistReq_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &cid_tcam_req);
    }
    return ret;
}

int32
_sys_usw_diag_bist_enqueue_tcam_req_prepare(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 buf[12] = {0xff,0,0,
                      0,0,0,
                      0,0,0,
                      0,0,0};
    uint8  loop = 0;
    QMgrEnqTcamBistReqFa_m  enqueue_tcam_req;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM; loop++)
    {
        buf[0] = 0xff - loop;
        sal_memset(&enqueue_tcam_req, 0 , sizeof(QMgrEnqTcamBistReqFa_m));
        sal_memcpy(&enqueue_tcam_req, buf,  12);/*80bits = 12byte,rtl auto align */
        SetQMgrEnqTcamBistReqFa(V,bistReqKeySize_f,  &enqueue_tcam_req, 0);
        SetQMgrEnqTcamBistReqFa(V,bistReqKeyValid_f, &enqueue_tcam_req, 1);
        cmd = DRV_IOW(QMgrEnqTcamBistReqFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &enqueue_tcam_req);

    }
    return ret;
}

int32
_sys_usw_diag_bist_mem_delete(uint8 lchip, sys_usw_diag_bist_tcam_t type, uint32 tbl_index)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 i = 0;
    uint16 loop;
    ds_t  ds;
    sal_memset(ds, 0 , sizeof(ds_t));
    switch (type)
    {
        
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM; i++)
            {
                cmd = DRV_IOW(ProgramIngAclTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM; i++)
            {
                cmd = DRV_IOW(ProgramEgrAclTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM; i++)
            {
                cmd = DRV_IOW(DsEgrLtidSelectTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM; i++)
            {
                cmd = DRV_IOW(DsLtidSelectTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;


        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_FLOW_REQ_MEM; i++)
            {
                cmd = DRV_IOW(FlowTcamTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_LPM_REQ_MEM; i++)
            {
                cmd = DRV_IOW(LpmTcamTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_CID_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_CID_REQ_MEM; i++)
            {
                cmd = DRV_IOW(IpeCidTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_ENQUEUE_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM; i++)
            {
                cmd = DRV_IOW(QMgrEnqTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, cmd, ds);
            }
            break;

        case SYS_USW_DIAG_BIST_TIDSELECT_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM; i++)
            {
                for(loop=0; loop < 16; loop++)
                {
                    cmd = DRV_IOW(DsLtidSelectTcamMem_t, DRV_ENTRY_FLAG);
                    DRV_IOCTL(lchip, i+loop*32, DRV_CMD_PP_EN(cmd), ds);
                }
            }
            break;

        case SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM; i++)
            {
                cmd = DRV_IOW(EgrSclHashTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;

        case SYS_USW_DIAG_BIST_EGRACL_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_EGRACL_REQ_MEM; i++)
            {
               cmd = DRV_IOW(EgressAclTcamTcamMem_t, DRV_ENTRY_FLAG);
               DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM; i++)
            {
              cmd = DRV_IOW(IpeHdrAdjRouterMacTcamMem_t, DRV_ENTRY_FLAG);
              DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM; i++)
            {
                cmd = DRV_IOW(IpeHdrAdjUdfTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_PROGRAMACL_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM; i++)
            {
                cmd = DRV_IOW(ProgramAclTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        case SYS_USW_DIAG_BIST_USERIDHASH_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM; i++)
             {
                cmd = DRV_IOW(UserIdHashTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
             }
            break;

        case SYS_USW_DIAG_BIST_USERID_TCAM:
            for (i = tbl_index; i < tbl_index + SYS_USW_DIAG_BIST_USERID_REQ_MEM; i++)
            {
                cmd = DRV_IOW(UserIdTcamMem_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, i, DRV_CMD_PP_EN(cmd), ds);
            }
            break;
        default:
            break;
    }
    return ret;
}

int32
_sys_usw_diag_bist_trigger(uint8 lchip, sys_usw_diag_bist_tcam_t type, uint8 enable, uint32 flow_tcam_index)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 enable_u32 = enable;
    FlowTcamBistCtl_m     flow_bist_ctl;
    IpeCidTcamBistCtl_m   cid_bist_ctl;
    QMgrEnqTcamBistCtl_m  enqueue_bist_ctl;
    ProgramAclLtidTcamBistCtl_m ltidt_bist_ctl;
    EgrSclHashTcamBistCtl_m egrsclhash_bist_ctl;
    EgressAclTcamBistCtl_m egraclhash_bist_ctl;

    IpeHdrAdjRouterMacTcamBistCtl_m     IpeHdrAdjRouterMac_bist_ctl;
    IpeHdrAdjUdfTcamBistCtl_m           IpeHdrAdjUdf_bist_ctl;
    ProgramAclTcamBistCtl_m             ProgramAcl_bist_ctl;
    UserIdHashTcamBistCtl_m             UserIdHash_bist_ctl;
    UserIdTcamBistCtl_m                 UserId_bist_ctl;

    ProgramIngAclTcamBistCtl_m      ProgramAcl_igs_bist_ctl;
    ProgramEgrAclTcamBistCtl_m      ProgramAcl_egs_bist_ctl;
    ProgramEgrAclLtidTcamBistCtl_m  ProgramAcl_egs_Ltid_ctl;
    ProgramIngAclLtidTcamBistCtl_m  ProgramAcl_igs_Ltid_ctl;

    sal_memset(&flow_bist_ctl, 0 , sizeof(FlowTcamBistCtl_m));
    sal_memset(&cid_bist_ctl, 0 , sizeof(IpeCidTcamBistCtl_m));
    sal_memset(&enqueue_bist_ctl, 0 , sizeof(QMgrEnqTcamBistCtl_m));
    sal_memset(&ltidt_bist_ctl, 0 , sizeof(ProgramAclLtidTcamBistCtl_m));
    sal_memset(&egrsclhash_bist_ctl, 0 , sizeof(EgrSclHashTcamBistCtl_m));
    sal_memset(&IpeHdrAdjRouterMac_bist_ctl, 0 , sizeof(IpeHdrAdjRouterMacTcamBistCtl_m));
    sal_memset(&IpeHdrAdjUdf_bist_ctl, 0 , sizeof(IpeHdrAdjUdfTcamBistCtl_m));
    sal_memset(&UserIdHash_bist_ctl, 0 , sizeof(UserIdHashTcamBistCtl_m));
    sal_memset(&UserId_bist_ctl, 0 , sizeof(UserIdTcamBistCtl_m));
    sal_memset(&egraclhash_bist_ctl, 0 , sizeof(EgressAclTcamBistCtl_m));
    sal_memset(&ProgramAcl_bist_ctl, 0 , sizeof(ProgramAclTcamBistCtl_m));

    sal_memset(&ProgramAcl_igs_bist_ctl, 0 , sizeof(ProgramIngAclTcamBistCtl_m));
    sal_memset(&ProgramAcl_egs_bist_ctl, 0 , sizeof(ProgramEgrAclTcamBistCtl_m));
    sal_memset(&ProgramAcl_egs_Ltid_ctl, 0 , sizeof(ProgramEgrAclLtidTcamBistCtl_m));
    sal_memset(&ProgramAcl_igs_Ltid_ctl, 0 , sizeof(ProgramIngAclLtidTcamBistCtl_m));

    switch (type)
    {
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM:
            if(enable)
            {
               SetProgramIngAclTcamBistCtl(V, cfgAclBistEn0_f,   &ProgramAcl_igs_bist_ctl, 1 << (flow_tcam_index / SYS_USW_DIAG_BIST_RAM_SZ_512));
            }
            else
            {
               SetProgramIngAclTcamBistCtl(V, cfgAclBistEn0_f,   &ProgramAcl_igs_bist_ctl, 0);
            }
            SetProgramIngAclTcamBistCtl(V, cfgAclBistOnce_f, &ProgramAcl_igs_bist_ctl, 1);
            SetProgramIngAclTcamBistCtl(V, cfgAclCaptureIndexDly_f, &ProgramAcl_igs_bist_ctl, 1);
            SetProgramIngAclTcamBistCtl(V, cfgAclBistOrCaptureStart_f, &ProgramAcl_igs_bist_ctl, 1);
            cmd = DRV_IOW(ProgramIngAclTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_igs_bist_ctl);
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM:
            if(enable)
            {
               SetProgramEgrAclTcamBistCtl(V, cfgAclBistEn0_f,   &ProgramAcl_egs_bist_ctl, 1 << (flow_tcam_index / SYS_USW_DIAG_BIST_RAM_SZ_256));
            }
            else
            {
               SetProgramEgrAclTcamBistCtl(V, cfgAclBistEn0_f,   &ProgramAcl_egs_bist_ctl, 0);
            }
            SetProgramEgrAclTcamBistCtl(V, cfgAclBistOnce_f, &ProgramAcl_egs_bist_ctl, 1);
            SetProgramEgrAclTcamBistCtl(V, cfgAclCaptureIndexDly_f, &ProgramAcl_egs_bist_ctl, 1);
            SetProgramEgrAclTcamBistCtl(V, cfgAclBistOrCaptureStart_f, &ProgramAcl_egs_bist_ctl, 1);
            cmd = DRV_IOW(ProgramEgrAclTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_egs_bist_ctl);
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM:
            SetProgramEgrAclLtidTcamBistCtl(V, cfgLtidTcamBistEn_f,   &ProgramAcl_egs_Ltid_ctl, enable);
            SetProgramEgrAclLtidTcamBistCtl(V, cfgLtidTcamBistOnce_f, &ProgramAcl_egs_Ltid_ctl, 1);
            SetProgramEgrAclLtidTcamBistCtl(V, cfgLtidTcamCaptureIndexDly_f, &ProgramAcl_egs_Ltid_ctl, 1);
            cmd = DRV_IOW(ProgramEgrAclLtidTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_egs_Ltid_ctl);
            break;
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM:
            SetProgramIngAclLtidTcamBistCtl(V, cfgLtidTcamBistEn_f,   &ProgramAcl_igs_Ltid_ctl, enable);
            SetProgramIngAclLtidTcamBistCtl(V, cfgLtidTcamBistOnce_f, &ProgramAcl_igs_Ltid_ctl, 1);
            SetProgramIngAclLtidTcamBistCtl(V, cfgLtidTcamCaptureIndexDly_f, &ProgramAcl_igs_Ltid_ctl, 1);
            cmd = DRV_IOW(ProgramIngAclLtidTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_igs_Ltid_ctl);
            break;

        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            if (enable_u32)
            {
                uint32 flag = flow_tcam_index / SYS_USW_DIAG_BIST_FLOW_RAM_SZ;
                enable_u32 = 0;
                CTC_BIT_SET(enable_u32, flag);
            }
            SetFlowTcamBistCtl(V,cfgBistEn_f, &flow_bist_ctl, enable_u32);
            SetFlowTcamBistCtl(V,cfgBistOnce_f, &flow_bist_ctl, 1);
            SetFlowTcamBistCtl(V,cfgCaptureIndexDly_f, &flow_bist_ctl, 1);
            cmd = DRV_IOW(FlowTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &flow_bist_ctl);
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM0:
            field_val = enable;
            cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgDaSa0BistEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
            if (enable == 0)
            {
                field_val = 1;
                cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgDaSa0BistOnce_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
                field_val = (DRV_FROM_AT(lchip)? 5: 4);
                cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgCaptureIndexDly_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM1:
            field_val = enable;
            cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgDaSa1BistEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
            if (enable == 0)
            {
                field_val = 1;
                cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgDaSa1BistOnce_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
                field_val = (DRV_FROM_AT(lchip)? 5: 4);
                cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgCaptureIndexDly_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM2:
            field_val = enable;
            cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgShareBistEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
            if (enable == 0)
            {
                field_val = 1;
                cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgShareBistOnce_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
                field_val = (DRV_FROM_AT(lchip)? 5: 4);
                cmd = DRV_IOW(LpmTcamBistCtrl_t, LpmTcamBistCtrl_cfgCaptureIndexDly_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));
            }
            break;
        case SYS_USW_DIAG_BIST_CID_TCAM:
            SetIpeCidTcamBistCtl(V,cfgBistEn_f, &cid_bist_ctl, enable);
            SetIpeCidTcamBistCtl(V,cfgBistOnce_f, &cid_bist_ctl, 1);
            SetIpeCidTcamBistCtl(V,cfgCaptureIndexDly_f, &cid_bist_ctl, (DRV_FROM_AT(lchip)? 2: 1));
            cmd = DRV_IOW(IpeCidTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &cid_bist_ctl);
            break;
        case SYS_USW_DIAG_BIST_ENQUEUE_TCAM:
            SetQMgrEnqTcamBistCtl(V, tcamCfgBistEn_f,   &enqueue_bist_ctl, enable);
            SetQMgrEnqTcamBistCtl(V, tcamCfgBistOnce_f, &enqueue_bist_ctl, 1);
            SetQMgrEnqTcamBistCtl(V, tcamCfgCaptureIndexDly_f, &enqueue_bist_ctl, 1);
            cmd = DRV_IOW(QMgrEnqTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &enqueue_bist_ctl);
            break;

        case SYS_USW_DIAG_BIST_TIDSELECT_TCAM:
            SetProgramAclLtidTcamBistCtl(V, cfgLtidTcamBistEn_f,   &ltidt_bist_ctl, enable);
            SetProgramAclLtidTcamBistCtl(V, cfgLtidTcamBistOnce_f, &ltidt_bist_ctl, 1);
            SetProgramAclLtidTcamBistCtl(V, cfgLtidTcamCaptureIndexDly_f, &ltidt_bist_ctl, 0);
            cmd = DRV_IOW(ProgramAclLtidTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ltidt_bist_ctl);
            break;

        case SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM:
            if(enable)
            {
                SetEgrSclHashTcamBistCtl(V, cfgBistEn_f,   &egrsclhash_bist_ctl, 1 << (flow_tcam_index / SYS_USW_DIAG_BIST_RAM_SZ_256));
            }
            else
            {
                SetEgrSclHashTcamBistCtl(V, cfgBistEn_f,   &egrsclhash_bist_ctl, 0);
            }
            SetEgrSclHashTcamBistCtl(V, cfgBistOnce_f, &egrsclhash_bist_ctl, 1);
            SetEgrSclHashTcamBistCtl(V, cfgCaptureIndexDly_f, &egrsclhash_bist_ctl, (DRV_FROM_AT(lchip)? 2: 1));
            cmd = DRV_IOW(EgrSclHashTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &egrsclhash_bist_ctl);
            break;

        case SYS_USW_DIAG_BIST_EGRACL_TCAM:
            if(enable)
            {
                SetEgressAclTcamBistCtl(V, cfgBistEn_f,   &egraclhash_bist_ctl, 1 << (flow_tcam_index / SYS_USW_DIAG_BIST_RAM_SZ_1K));
            }
            else
            {
                SetEgressAclTcamBistCtl(V, cfgBistEn_f,   &egraclhash_bist_ctl, 0);
            }
            SetEgressAclTcamBistCtl(V, cfgBistOnce_f, &egraclhash_bist_ctl, 1);
            SetEgressAclTcamBistCtl(V, cfgCaptureIndexDly_f, &egraclhash_bist_ctl, 3);
            cmd = DRV_IOW(EgressAclTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &egraclhash_bist_ctl);
            break;

        case SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM:
            SetIpeHdrAdjRouterMacTcamBistCtl(V, tcamCfgBistEn_f,   &IpeHdrAdjRouterMac_bist_ctl, enable);
            SetIpeHdrAdjRouterMacTcamBistCtl(V, tcamCfgBistOnce_f, &IpeHdrAdjRouterMac_bist_ctl, 1);
            SetIpeHdrAdjRouterMacTcamBistCtl(V, tcamCfgCaptureIndexDly_f, &IpeHdrAdjRouterMac_bist_ctl, (DRV_FROM_AT(lchip)? 2: 1));
            cmd = DRV_IOW(IpeHdrAdjRouterMacTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &IpeHdrAdjRouterMac_bist_ctl);
            break;

        case SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM:
            SetIpeHdrAdjUdfTcamBistCtl(V, udfTcamCfgBistEn_f,   &IpeHdrAdjUdf_bist_ctl, enable);
            SetIpeHdrAdjUdfTcamBistCtl(V, udfTcamCfgBistOnce_f, &IpeHdrAdjUdf_bist_ctl, 1);
            SetIpeHdrAdjUdfTcamBistCtl(V, udfTcamCfgCaptureIndexDly_f, &IpeHdrAdjUdf_bist_ctl, (DRV_FROM_AT(lchip)? 2: 1));
            cmd = DRV_IOW(IpeHdrAdjUdfTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &IpeHdrAdjUdf_bist_ctl);
            break;

        case SYS_USW_DIAG_BIST_PROGRAMACL_TCAM:
            if(enable)
            {
               SetProgramAclTcamBistCtl(V, cfgAclBistEn0_f,   &ProgramAcl_bist_ctl, 1 << (flow_tcam_index / SYS_USW_DIAG_BIST_RAM_SZ_2K));
            }
            else
            {
               SetProgramAclTcamBistCtl(V, cfgAclBistEn0_f,   &ProgramAcl_bist_ctl, 0);
            }
            SetProgramAclTcamBistCtl(V, cfgAclBistOnce_f, &ProgramAcl_bist_ctl, 1);
            SetProgramAclTcamBistCtl(V, cfgAclCaptureIndexDly_f, &ProgramAcl_bist_ctl, 1);
            SetProgramAclTcamBistCtl(V, cfgAclBistOrCaptureStart_f, &ProgramAcl_bist_ctl, 1);
            cmd = DRV_IOW(ProgramAclTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_bist_ctl);
            break;
        case SYS_USW_DIAG_BIST_USERIDHASH_TCAM:
            if(enable)
            {
                SetUserIdHashTcamBistCtl(V, cfgBistEn_f,   &UserIdHash_bist_ctl, 1 << (flow_tcam_index / SYS_USW_DIAG_BIST_RAM_SZ_512));
            }
            else
            {
                SetUserIdHashTcamBistCtl(V, cfgBistEn_f,   &UserIdHash_bist_ctl, 0);
            }
            SetUserIdHashTcamBistCtl(V, cfgBistOnce_f, &UserIdHash_bist_ctl, 1);
            SetUserIdHashTcamBistCtl(V, cfgCaptureIndexDly_f, &UserIdHash_bist_ctl, (DRV_FROM_AT(lchip)? 5: 4));
            cmd = DRV_IOW(UserIdHashTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &UserIdHash_bist_ctl);
            break;
        case SYS_USW_DIAG_BIST_USERID_TCAM:
            if(enable)
            {
               SetUserIdTcamBistCtl(V, cfgBistEn_f,   &UserId_bist_ctl, 1 << (flow_tcam_index / SYS_USW_DIAG_BIST_RAM_SZ_1K));
            }
            else
            {

               SetUserIdTcamBistCtl(V, cfgBistEn_f,   &UserId_bist_ctl, 0);
            }
            SetUserIdTcamBistCtl(V, cfgBistOnce_f, &UserId_bist_ctl, 1);
            SetUserIdTcamBistCtl(V, cfgCaptureIndexDly_f, &UserId_bist_ctl, (DRV_FROM_AT(lchip)? 5: 4));
            cmd = DRV_IOW(UserIdTcamBistCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &UserId_bist_ctl);
            break;            
        default:
            break;
    }
    return ret;
}

int32
_sys_usw_diag_bist_done(uint8 lchip, sys_usw_diag_bist_tcam_t type)
{
    int32  ret = CTC_E_NONE;
    uint8  wait_cnt = 0;
    uint32 done    = 0;
    uint32 cmd  = 0;
    switch (type)
    {
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM:
             cmd=DRV_IOR(ProgramIngAclTcamBistCtl_t, ProgramIngAclTcamBistCtl_aclTcamBistDone_f);
             break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM:
             cmd=DRV_IOR(ProgramEgrAclTcamBistCtl_t, ProgramEgrAclTcamBistCtl_aclTcamBistDone_f);
             break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM:
             cmd=DRV_IOR(ProgramEgrAclLtidTcamBistCtl_t, ProgramEgrAclLtidTcamBistCtl_ltidTcamBistDone_f);
             break;
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM:
             cmd=DRV_IOR(ProgramIngAclLtidTcamBistCtl_t, ProgramIngAclLtidTcamBistCtl_ltidTcamBistDone_f);
             break;
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            cmd= DRV_IOR(FlowTcamBistStatus_t, FlowTcamBistStatus_bistDone_f);
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM0:
            cmd = DRV_IOR(LpmTcamBistStatus_t, LpmTcamBistStatus_daSa0BistDone_f);
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM1:
            cmd= DRV_IOR(LpmTcamBistStatus_t, LpmTcamBistStatus_daSa1BistDone_f);
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM2:
            cmd= DRV_IOR(LpmTcamBistStatus_t, LpmTcamBistStatus_shareBistDone_f);
            break;
        case SYS_USW_DIAG_BIST_CID_TCAM:
            cmd = DRV_IOR(IpeCidTcamBistStatus_t, IpeCidTcamBistStatus_bistDone_f);
            break;
        case SYS_USW_DIAG_BIST_ENQUEUE_TCAM:
            cmd = DRV_IOR(QMgrEnqTcamBistStatus_t, QMgrEnqTcamBistStatus_tcamBistDone_f);
            break;
        case SYS_USW_DIAG_BIST_TIDSELECT_TCAM:
            cmd = DRV_IOR(ProgramAclLtidTcamBistCtl_t, ProgramAclLtidTcamBistCtl_ltidTcamBistDone_f);
            break;
        case SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM:
            cmd=DRV_IOR( EgrSclHashTcamBistStatus_t, EgrSclHashTcamBistStatus_tcamBistDone_f);
            break;
        case SYS_USW_DIAG_BIST_EGRACL_TCAM:
            cmd=DRV_IOR( EgresAclTcamBistStatus_t, EgresAclTcamBistStatus_tcamBistDone_f);
            break;
        case SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM:
            cmd=DRV_IOR(IpeHdrAdjRouterMacTcamBistStatus_t, IpeHdrAdjRouterMacTcamBistStatus_tcamBistDone_f);
            break;
        case SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM:
             cmd=DRV_IOR(IpeHdrAdjUdfTcamBistStatus_t, IpeHdrAdjUdfTcamBistStatus_udfTcamBistDone_f);
             break;
        case SYS_USW_DIAG_BIST_PROGRAMACL_TCAM:
             cmd=DRV_IOR(ProgramAclTcamBistCtl_t, ProgramAclTcamBistCtl_aclTcamBistDone_f);
             break;
        case SYS_USW_DIAG_BIST_USERIDHASH_TCAM:
             cmd=DRV_IOR(UserIdHashTcamBistStatus_t, UserIdHashTcamBistStatus_tcamBistDone_f);
             break;
        case SYS_USW_DIAG_BIST_USERID_TCAM:
             cmd=DRV_IOR(UserIdTcamBistStatus_t, UserIdTcamBistStatus_tcamBistDone_f);
             break;

        default:
            break;
    }
    while (1)
    {
        DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &done);
        if (done)
        {
            return CTC_E_NONE;
        }
        else
        {
            wait_cnt++;
            if (10 == wait_cnt)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "TCAM BIST OUT OF TIME!\n");
                return CTC_E_HW_TIME_OUT;
            }
            sal_task_sleep(1);
        }
    }
    return ret;
}

int32
_sys_usw_diag_bist_flow_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 index_tcam = 0;
    FlowTcamBistResultFA_m     flow_bist_result;
    FlowTcamBistCtl_m          flow_bist_ctl;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_FLOW_REQ_MEM; loop++)
    {
        sal_memset(&flow_bist_result, 0 , sizeof(FlowTcamBistResultFA_m));
        cmd = DRV_IOR(FlowTcamBistResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &flow_bist_result);
        GetFlowTcamBistResultFA(A, realIndexHit_f, &flow_bist_result, &field_value);
        if (field_value)
        {
            GetFlowTcamBistResultFA(A,realIndex_f, &flow_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Flow-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Flow-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index ++;
    }
    if (*p_ramid)
    {
        uint32 bmp_bisten = 0;
        cmd = DRV_IOR(FlowTcamBistCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flow_bist_ctl));
        bmp_bisten = GetFlowTcamBistCtl(V, cfgBistEn_f, &flow_bist_ctl);
        CTC_BIT_FIRST_VALID(bmp_bisten,15,index_tcam);

        *p_ramid = DRV_FTM_TCAM_KEY0 + index_tcam;
    }
    return ret;
}

int32
_sys_usw_diag_bist_lpm_tcam_result(uint8 lchip, uint8 lpm_id, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;

    LpmTcamBistResult0FA_m     lpm_bist_result;
    if (0 == lpm_id)
    {
        cmd = DRV_IOR(LpmTcamBistResult0FA_t, DRV_ENTRY_FLAG);
    }
    else if (1 == lpm_id)
    {
        cmd = DRV_IOR(LpmTcamBistResult1FA_t, DRV_ENTRY_FLAG);
    }
    else
    {
        cmd = DRV_IOR(LpmTcamBistResult2FA_t, DRV_ENTRY_FLAG);
    }
    for (loop = 0; loop < SYS_USW_DIAG_BIST_LPM_REQ_MEM; loop++)
    {
        sal_memset(&lpm_bist_result, 0 , sizeof(LpmTcamBistResult0FA_m));
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &lpm_bist_result);
        GetLpmTcamBistResult0FA(A,realIndex0Hit_f, &lpm_bist_result, &field_value);
        if (field_value)
        {
            GetLpmTcamBistResult0FA(A,realIndex0_f, &lpm_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare lpm-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST lpm-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        if (lpm_id != 2)
        {
            *p_ramid = DRV_FTM_LPM_TCAM_KEY0 + lpm_id*4 + ((index - lpm_id*8192)/1024);
        }
        else
        {
            *p_ramid = DRV_FTM_LPM_TCAM_KEY0 + lpm_id*4 + ((index - lpm_id*8192)/2048);
        }
    }
    return ret;
}

int32
_sys_usw_diag_bist_enq_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    QMgrEnqTcamBistResultFa_m     enq_bist_result;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM; loop++)
    {
        sal_memset(&enq_bist_result, 0 , sizeof(QMgrEnqTcamBistResultFa_m));
        cmd = DRV_IOR(QMgrEnqTcamBistResultFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &enq_bist_result);
        GetQMgrEnqTcamBistResultFa(A,realIndexHit_f, &enq_bist_result, &field_value);
        if (field_value)
        {
            GetQMgrEnqTcamBistResultFa(A,realIndex_f, &enq_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare ENQUEUE-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST ENQUEUE-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        *p_ramid = DRV_FTM_QUEUE_TCAM;
    }
    return ret;
}


int32
_sys_usw_diag_bist_egracl_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 index_tcam = 0;
    EgressAclTcamBistResultFa_m  egraclhash_bist_result;
    EgressAclTcamBistCtl_m       egraclhash_bist_ctl;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM; loop++)
    {
        sal_memset(&egraclhash_bist_result, 0 , sizeof(EgressAclTcamBistResultFa_m));
        cmd = DRV_IOR(EgressAclTcamBistResultFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &egraclhash_bist_result);
        GetEgressAclTcamBistResultFa(A,realIndexHit_f, &egraclhash_bist_result, &field_value);
        if (field_value)
        {
            GetEgressAclTcamBistResultFa(A,realIndex_f, &egraclhash_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Egraclhash-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Egraclhash-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        uint32 bmp_bisten = 0;
        cmd = DRV_IOR(EgressAclTcamBistCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &egraclhash_bist_ctl));
        bmp_bisten = GetEgressAclTcamBistCtl(V, cfgBistEn_f, &egraclhash_bist_ctl);
        CTC_BIT_FIRST_VALID(bmp_bisten,4,index_tcam);

        *p_ramid = DRV_FTM_TCAM_KEY20 + index_tcam;
    }
    return ret;
}

int32
_sys_usw_diag_bist_useridhash_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 index_tcam = 0;
    UserIdHashTcamBistResultFa_m useridhash_bist_result;
    UserIdHashTcamBistCtl_m      UserIdHash_bist_ctl;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM; loop++)
    {
        sal_memset(&useridhash_bist_result, 0 , sizeof(UserIdHashTcamBistResultFa_m));
        cmd = DRV_IOR(UserIdHashTcamBistResultFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &useridhash_bist_result);
        GetUserIdHashTcamBistResultFa(A,realIndexHit_f, &useridhash_bist_result, &field_value);
        if (field_value)
        {
            GetUserIdHashTcamBistResultFa(A,realIndex_f, &useridhash_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Useridhash-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Useridhash-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        uint32 bmp_bisten = 0;
        cmd = DRV_IOR(UserIdHashTcamBistCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &UserIdHash_bist_ctl));
        bmp_bisten = GetUserIdHashTcamBistCtl(V, cfgBistEn_f, &UserIdHash_bist_ctl);
        CTC_BIT_FIRST_VALID(bmp_bisten,2,index_tcam);

        *p_ramid = DRV_FTM_TCAM_KEY0 + index_tcam;
    }
    return ret;
}


int32
_sys_usw_diag_bist_egs_progrmacl_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 index_tcam = 0;
    ProgramEgrAclTcamBist0ResultFA_m  progrmacl_egs_bist_result;
    ProgramEgrAclTcamBistCtl_m        ProgramAcl_egs_bist_ctl;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM; loop++)
    {
        sal_memset(&progrmacl_egs_bist_result, 0 , sizeof(ProgramEgrAclTcamBist0ResultFA_m));
        cmd = DRV_IOR(ProgramEgrAclTcamBist0ResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &progrmacl_egs_bist_result);
        GetProgramEgrAclTcamBist0ResultFA(A,indexHit_f, &progrmacl_egs_bist_result, &field_value);
        if (field_value)
        {
            GetProgramEgrAclTcamBist0ResultFA(A,resultIndex_f, &progrmacl_egs_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Progrmacl-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Progrmacl-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {   
        uint32 bmp_bisten = 0;
        cmd = DRV_IOR(ProgramEgrAclTcamBistCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_egs_bist_ctl));
        bmp_bisten = GetProgramEgrAclTcamBistCtl(V, cfgAclBistEn0_f, &ProgramAcl_egs_bist_ctl);
        CTC_BIT_FIRST_VALID(bmp_bisten,12,index_tcam);

        *p_ramid = DRV_FTM_TCAM_KEY28 + index_tcam;
    }
    return ret;
}

int32
_sys_usw_diag_bist_igs_progrmacl_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 index_tcam = 0;
    ProgramIngAclTcamBist0ResultFA_m progrmacl_igs_bist_result;
    ProgramIngAclTcamBistCtl_m      ProgramAcl_igs_bist_ctl;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM; loop++)
    {
        sal_memset(&progrmacl_igs_bist_result, 0 , sizeof(ProgramIngAclTcamBist0ResultFA_m));
        cmd = DRV_IOR(ProgramIngAclTcamBist0ResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &progrmacl_igs_bist_result);
        GetProgramIngAclTcamBist0ResultFA(A,indexHit_f, &progrmacl_igs_bist_result, &field_value);
        if (field_value)
        {
            GetProgramIngAclTcamBist0ResultFA(A,resultIndex_f, &progrmacl_igs_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Progrmacl-igs-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Progrmacl-igs-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        uint32 bmp_bisten = 0;
        cmd = DRV_IOR(ProgramIngAclTcamBistCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_igs_bist_ctl));
        bmp_bisten = GetProgramIngAclTcamBistCtl(V, cfgAclBistEn0_f, &ProgramAcl_igs_bist_ctl);
        CTC_BIT_FIRST_VALID(bmp_bisten,24,index_tcam);
        *p_ramid = DRV_FTM_TCAM_KEY4 + index_tcam ;
    }
    return ret;
}

int32
_sys_usw_diag_bist_progrmacl_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 index_tcam = 0;
    ProgramAclTcamBist0ResultFA_m  progrmacl_bist_result;
    ProgramAclTcamBistCtl_m        ProgramAcl_bist_ctl;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM; loop++)
    {
        sal_memset(&progrmacl_bist_result, 0 , sizeof(ProgramAclTcamBist0ResultFA_m));
        cmd = DRV_IOR(ProgramAclTcamBist0ResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &progrmacl_bist_result);
        GetProgramAclTcamBist0ResultFA(A,indexHit_f, &progrmacl_bist_result, &field_value);
        if (field_value)
        {
            GetProgramAclTcamBist0ResultFA(A,resultIndex_f, &progrmacl_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Progrmacl-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Progrmacl-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        uint32 bmp_bisten = 0;
        cmd = DRV_IOR(ProgramAclTcamBistCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ProgramAcl_bist_ctl));
        bmp_bisten = GetProgramAclTcamBistCtl(V, cfgAclBistEn0_f, &ProgramAcl_bist_ctl);
        CTC_BIT_FIRST_VALID(bmp_bisten,16,index_tcam);

        *p_ramid = DRV_FTM_TCAM_KEY4 + index_tcam;
    }
    return ret;
}

int32
_sys_usw_diag_bist_ipehdrotemac_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    IpeHdrAdjRouterMacTcamBistResultFa_m  ipehdrotemac_bist_result;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM; loop++)
    {
        sal_memset(&ipehdrotemac_bist_result, 0 , sizeof(IpeHdrAdjRouterMacTcamBistResultFa_m));
        cmd = DRV_IOR(IpeHdrAdjRouterMacTcamBistResultFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ipehdrotemac_bist_result);
        GetIpeHdrAdjRouterMacTcamBistResultFa(A,realIndexHit_f, &ipehdrotemac_bist_result, &field_value);
        if (field_value)
        {
            GetIpeHdrAdjRouterMacTcamBistResultFa(A,realIndex_f, &ipehdrotemac_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Ipehdrotemac-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Ipehdrotemac-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        *p_ramid = DRV_FTM_RMAC_TCAM;
    }
    return ret;
}


int32
_sys_usw_diag_bist_cid_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    IpeCidTcamBistResult_m     cid_bist_result;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_CID_REQ_MEM; loop++)
    {
        sal_memset(&cid_bist_result, 0 , sizeof(IpeCidTcamBistResult_m));
        cmd = DRV_IOR(IpeCidTcamBistResult_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &cid_bist_result);
        GetIpeCidTcamBistResult(A, readIndexHit_f, &cid_bist_result, &field_value);
        if (field_value)
        {
            GetIpeCidTcamBistResult(A,readIndex_f, &cid_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare CID-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST CID-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        *p_ramid = DRV_FTM_CID_TCAM;
    }
    return ret;
}

int32
_sys_usw_diag_bist_userid_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    UserIdTcamBistResultFa_m userid_bist_result;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM; loop++)
    {
        sal_memset(&userid_bist_result, 0 , sizeof(UserIdTcamBistResultFa_m));
        cmd = DRV_IOR(UserIdTcamBistResultFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &userid_bist_result);
        GetUserIdTcamBistResultFa(A,realIndexHit_f, &userid_bist_result, &field_value);
        if (field_value)
        {
            GetUserIdTcamBistResultFa(A,realIndex_f, &userid_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Userid-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Userid-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        *p_ramid = DRV_FTM_TCAM_KEY2 + index / SYS_USW_DIAG_BIST_RAM_SZ_512 ;
    }
    return ret;
}

int32
_sys_usw_diag_bist_ipehdudf_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    IpeHdrAdjUdfTcamBistResultFa_m  ipehdrotemac_bist_result;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM; loop++)
    {
        sal_memset(&ipehdrotemac_bist_result, 0 , sizeof(IpeHdrAdjUdfTcamBistResultFa_m));
        cmd = DRV_IOR(IpeHdrAdjUdfTcamBistResultFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, cmd, &ipehdrotemac_bist_result);
        GetIpeHdrAdjUdfTcamBistResultFa(A,realIndexHit_f, &ipehdrotemac_bist_result, &field_value);
        if (field_value)
        {
            GetIpeHdrAdjUdfTcamBistResultFa(A,realIndex_f, &ipehdrotemac_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Ipehdudf-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Ipehdudf-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        *p_ramid = DRV_FTM_UDF_TCAM;
    }
    return ret;
}

int32
_sys_usw_diag_bist_egrsclhash_tcam_result(uint8 lchip, uint32 index, sys_usw_diag_bist_tcam_t type,  uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 index_tcam = 0;
    EgrSclHashTcamBistResultFa_m  egrsclhash_bist_result;
    EgrSclHashTcamBistCtl_m       egrsclhash_bist_ctl;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM; loop++)
    {
        sal_memset(&egrsclhash_bist_result, 0 , sizeof(EgrSclHashTcamBistResultFa_m));
        cmd = DRV_IOR(EgrSclHashTcamBistResultFa_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &egrsclhash_bist_result);
        GetEgrSclHashTcamBistResultFa(A,realIndexHit_f, &egrsclhash_bist_result, &field_value);
        if (field_value)
        {
            GetEgrSclHashTcamBistResultFa(A,realIndex_f, &egrsclhash_bist_result, &field_value);
            if (index != field_value)
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Egrsclhash-tcam Error! expect index[%d], actual index[%d]\n", index+loop, field_value);
                ret = CTC_E_HW_FAIL;
                *p_ramid = 1;
            }
        }
        else
        {
            SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Egrsclhash-tcam Not Hit! expect index[%d]\n", index);
            ret = CTC_E_HW_TIME_OUT;
            *p_ramid = 1;
        }
        index++;
    }
    if (*p_ramid)
    {
        uint32 bmp_bisten = 0;
        cmd = DRV_IOR(EgrSclHashTcamBistCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &egrsclhash_bist_ctl));
        bmp_bisten = GetEgrSclHashTcamBistCtl(V, cfgBistEn_f, &egrsclhash_bist_ctl);
        CTC_BIT_FIRST_VALID(bmp_bisten,2,index_tcam);
        *p_ramid = ( DRV_FROM_AT(lchip) ? DRV_FTM_TCAM_KEY40 : DRV_FTM_TCAM_KEY24 )+ index_tcam ;

    }
    return ret;
}


int32
_sys_usw_diag_bist_igs_ltidselect_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint16   loop2;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 step = ProgramIngAclLtidTcamBistResultFA_gLtidBistResult_1_indexHit_f - ProgramIngAclLtidTcamBistResultFA_gLtidBistResult_0_indexHit_f;
    ProgramIngAclLtidTcamBistResultFA_m ltidselect_igs_bist_result;

    for (loop = 0; loop < SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_REQ_MEM; loop++)
    {
        sal_memset(&ltidselect_igs_bist_result, 0 , sizeof(ProgramIngAclLtidTcamBistResultFA_m));

        cmd = DRV_IOR(ProgramIngAclLtidTcamBistResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ltidselect_igs_bist_result);

        for(loop2=0; loop2 < 24; loop2++)
        {
            GetProgramIngAclLtidTcamBistResultFA(A,gLtidBistResult_0_indexHit_f+loop2*step, &ltidselect_igs_bist_result, &field_value);
            if (field_value)
            {
                GetProgramIngAclLtidTcamBistResultFA(A,gLtidBistResult_0_resultIndex_f+loop2*step, &ltidselect_igs_bist_result, &field_value);
                if (index != field_value)
                {
                    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Ltidselect-tcam Error!  loop[%u], loop2[%u],expect index[%d], actual index[%d]\n", loop, loop2, index+loop, field_value);
                    ret = CTC_E_HW_FAIL;
                    *p_ramid = 1;
                }
            }
            else
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Ltidselect-tcam Not Hit! loop[%u], loop2[%u],expect index[%d]\n", loop, loop2, index);
                ret = CTC_E_HW_TIME_OUT;
                *p_ramid = 1;
            }
        }
        index++;
    }
    if (*p_ramid)
    {        
        *p_ramid = DRV_FTM_SEL_TCAM;
    }
    return ret;
}

int32
_sys_usw_diag_bist_egs_ltidselect_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint16   loop2;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 step = ProgramEgrAclLtidTcamBistResultFA_gLtidBistResult_1_indexHit_f - ProgramEgrAclLtidTcamBistResultFA_gLtidBistResult_0_indexHit_f;
    ProgramEgrAclLtidTcamBistResultFA_m ltidselect_egs_bist_result;

    
    for (loop = 0; loop < SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_REQ_MEM; loop++)
    {
        sal_memset(&ltidselect_egs_bist_result, 0 , sizeof(ProgramEgrAclLtidTcamBistResultFA_m));

        cmd = DRV_IOR(ProgramEgrAclLtidTcamBistResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ltidselect_egs_bist_result);

        for(loop2=0; loop2 < 12; loop2++)
        {
            GetProgramEgrAclLtidTcamBistResultFA(A,gLtidBistResult_0_indexHit_f+loop2*step, &ltidselect_egs_bist_result, &field_value);
            if (field_value)
            {
                GetProgramEgrAclLtidTcamBistResultFA(A,gLtidBistResult_0_resultIndex_f+loop2*step, &ltidselect_egs_bist_result, &field_value);
                if (index != field_value)
                {
                    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Ltidselect-tcam Error!  loop[%u], loop2[%u],expect index[%d], actual index[%d]\n", loop, loop2, index+loop, field_value);
                    ret = CTC_E_HW_FAIL;
                    *p_ramid = 1;
                }
            }
            else
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Ltidselect-tcam Not Hit! loop[%u], loop2[%u],expect index[%d]\n", loop, loop2, index);
                ret = CTC_E_HW_TIME_OUT;
                *p_ramid = 1;
            }
        }
        index++;
    }
    if (*p_ramid)
    {
        *p_ramid = DRV_FTM_SEL_TCAM_EGR;
    }
    return ret;
}

int32
_sys_usw_diag_bist_ltidselect_tcam_result(uint8 lchip, uint32 index, uint8* p_ramid)
{
    int32 ret = CTC_E_NONE;
    uint32  loop = 0;
    uint16   loop2;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 step = 0;
    ProgramLtidTcamBistResultFA_m ltidselect_bist_result;

    step = ProgramLtidTcamBistResultFA_gLtidBistResult_1_indexHit_f - ProgramLtidTcamBistResultFA_gLtidBistResult_0_indexHit_f;
    for (loop = 0; loop < SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM; loop++)
    {
        sal_memset(&ltidselect_bist_result, 0 , sizeof(ProgramLtidTcamBistResultFA_m));

        cmd = DRV_IOR(ProgramLtidTcamBistResultFA_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ltidselect_bist_result);

        for(loop2=0; loop2 < 16; loop2++)
        {
            GetProgramLtidTcamBistResultFA(A,gLtidBistResult_0_indexHit_f+loop2*step, &ltidselect_bist_result, &field_value);
            if (field_value)
            {
                GetProgramLtidTcamBistResultFA(A,gLtidBistResult_0_resultIndex_f+loop2*step, &ltidselect_bist_result, &field_value);
                if (index != field_value)
                {
                    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Compare Ltidselect-tcam Error!  loop[%u], loop2[%u],expect index[%d], actual index[%d]\n", loop, loop2, index+loop, field_value);
                    ret = CTC_E_HW_FAIL;
                    *p_ramid = 1;
                }
            }
            else
            {
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"MEM-BIST Ltidselect-tcam Not Hit! loop[%u], loop2[%u],expect index[%d]\n", loop, loop2, index);
                ret = CTC_E_HW_TIME_OUT;
                *p_ramid = 1;
            }
        }
        index++;
    }
    if (*p_ramid)
    {
        *p_ramid = DRV_FTM_SEL_TCAM;
    }
    return ret;
}


int32
_sys_usw_diag_bist_cmp_and_result(uint8 lchip, sys_usw_diag_bist_tcam_t type,uint8* err_mem_id)
{
    int32 ret = CTC_E_NONE;
    uint32 i = 0, j = 0;
    uint32 index = 0;
    uint32 lpm_per_tcam_max_index = 0;
    lpm_per_tcam_max_index = DRV_FROM_AT(lchip)? 8192: (DRV_TABLE_MAX_INDEX(lchip, LpmTcamTcamMem_t)/3);
    *err_mem_id = 0;

    switch (type)
    {

       case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM:
            for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, ProgramIngAclTcamMem_t) / SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM ); i++)
            {
               index = ( i*SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM ) % SYS_USW_DIAG_BIST_RAM_SZ_512;
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, i*SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM));
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, i*SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM));

               if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
               {
                   CTC_ERROR_RETURN(_sys_usw_diag_bist_igs_progrmacl_tcam_result(lchip, index, err_mem_id));
               }
               CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_IGS_PROGRAMACL_REQ_MEM));
            }
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM:
            for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, ProgramEgrAclTcamMem_t) / SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM ); i++)
            {
               index = ( i*SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM ) % SYS_USW_DIAG_BIST_RAM_SZ_256;
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, i*SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM));
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, i*SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM));

               if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
               {
                   CTC_ERROR_RETURN(_sys_usw_diag_bist_egs_progrmacl_tcam_result(lchip, index, err_mem_id));
               }
               CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_EGS_PROGRAMACL_REQ_MEM));
            }
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM:
            for (i = 0; i < (DRV_TABLE_MAX_INDEX(lchip, DsEgrLtidSelectTcamMem_t)/SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_REQ_MEM)/12; i++)
            {
                index = i*SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_REQ_MEM;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, 0));

                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_egs_ltidselect_tcam_result(lchip, index, err_mem_id));
                }
                for (j = 0; j < 12; j++)
                {
                    index = j*DRV_TABLE_MAX_INDEX(lchip, DsEgrLtidSelectTcamMem_t)/12 + i*SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_REQ_MEM;
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, index));
                }
            }
            break;
         case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM:
            for (i = 0; i < (DRV_TABLE_MAX_INDEX(lchip, DsLtidSelectTcamMem_t)/SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_REQ_MEM)/24; i++)
            {
                index = i*SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_REQ_MEM;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, 0));

                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_igs_ltidselect_tcam_result(lchip, index, err_mem_id));
                }
                for (j = 0; j < 24; j++)
                {
                    index = j*DRV_TABLE_MAX_INDEX(lchip, DsLtidSelectTcamMem_t)/24 + i*SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_REQ_MEM;
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, index));
                }
            }
            break;

        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            for (i = 0; i < ((DRV_TABLE_MAX_INDEX(lchip, FlowTcamTcamMem_t)- 4*SYS_USW_DIAG_BIST_FLOW_RAM_SZ)/SYS_USW_DIAG_BIST_FLOW_REQ_MEM); i++)
            {
                index = i*SYS_USW_DIAG_BIST_FLOW_REQ_MEM;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM, 0, index));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM, 1, index));
                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM))
                {
                    if ((CTC_E_NONE != _sys_usw_diag_bist_flow_tcam_result(lchip,index, err_mem_id))
                        && ((index%SYS_USW_DIAG_BIST_FLOW_RAM_SZ)/SYS_USW_DIAG_BIST_FLOW_RAM_INVALID_SZ))
                    {
                        *err_mem_id = 0;
                    }
                    if (*err_mem_id)
                    {
                        return ret;
                    }
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM, index));
            }
            break;
         case SYS_USW_DIAG_BIST_LPM_TCAM0:
            for (i = 0; i < lpm_per_tcam_max_index/SYS_USW_DIAG_BIST_LPM_REQ_MEM ; i++)
            {
                index = i*SYS_USW_DIAG_BIST_LPM_REQ_MEM;
                if(index >= LPM_TMM_INVALID_USED_MEM00(lchip) && index < LPM_TMM_INVALID_USED_MEM01(lchip))
                {
                    continue;
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM0, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM0, 1, 0));
                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, SYS_USW_DIAG_BIST_LPM_TCAM0))
                {
                  CTC_ERROR_RETURN(_sys_usw_diag_bist_lpm_tcam_result(lchip, 0, index, err_mem_id));
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, SYS_USW_DIAG_BIST_LPM_TCAM, i*SYS_USW_DIAG_BIST_LPM_REQ_MEM));
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM1:
            for (i = lpm_per_tcam_max_index/SYS_USW_DIAG_BIST_LPM_REQ_MEM; i < 2*(lpm_per_tcam_max_index/SYS_USW_DIAG_BIST_LPM_REQ_MEM); i++)
            {
                index = i*SYS_USW_DIAG_BIST_LPM_REQ_MEM;
                if(index >= LPM_TMM_INVALID_USED_MEM10(lchip) && index < LPM_TMM_INVALID_USED_MEM11(lchip))
                {
                    continue;
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM1, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM1, 1, 0));
                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, SYS_USW_DIAG_BIST_LPM_TCAM1))
                {
                   CTC_ERROR_RETURN(_sys_usw_diag_bist_lpm_tcam_result(lchip, 1, index, err_mem_id));
                 }
                 CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, SYS_USW_DIAG_BIST_LPM_TCAM, i*SYS_USW_DIAG_BIST_LPM_REQ_MEM));
            }
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM2:
            for (i = (lpm_per_tcam_max_index/SYS_USW_DIAG_BIST_LPM_REQ_MEM)*2; i < (lpm_per_tcam_max_index/SYS_USW_DIAG_BIST_LPM_REQ_MEM)*3; i++)
            {
                index = i*SYS_USW_DIAG_BIST_LPM_REQ_MEM;
                if(DRV_FROM_AT(lchip) && index >= LPM_AT_INVALID_USED_MEM10(lchip) && index < LPM_AT_INVALID_USED_MEM11(lchip))
                {
                    continue;
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM2, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM2, 1, 0));
                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, SYS_USW_DIAG_BIST_LPM_TCAM2))
                {
                  CTC_ERROR_RETURN(_sys_usw_diag_bist_lpm_tcam_result(lchip, 2, index, err_mem_id));
                 }
                 CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, SYS_USW_DIAG_BIST_LPM_TCAM, i*SYS_USW_DIAG_BIST_LPM_REQ_MEM));
            }
            break;
        case SYS_USW_DIAG_BIST_CID_TCAM:
            for (i = 0; i < (DRV_TABLE_MAX_INDEX(lchip, IpeCidTcamMem_t)/SYS_USW_DIAG_BIST_CID_REQ_MEM); i++)
            {
                index = i*SYS_USW_DIAG_BIST_CID_REQ_MEM;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_CID_TCAM, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_CID_TCAM, 1, 0));
                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, SYS_USW_DIAG_BIST_CID_TCAM))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_cid_tcam_result(lchip,index, err_mem_id));
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, SYS_USW_DIAG_BIST_CID_TCAM, i*SYS_USW_DIAG_BIST_CID_REQ_MEM));
            }
            break;
        case SYS_USW_DIAG_BIST_ENQUEUE_TCAM:
            for (i = 0; i < (DRV_TABLE_MAX_INDEX(lchip, QMgrEnqTcamMem_t)/SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM); i++)
            {
                index = i*SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, 0));
                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_enq_tcam_result(lchip, index, err_mem_id));
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_ENQUEUE_REQ_MEM));
            }
            break;

         case SYS_USW_DIAG_BIST_TIDSELECT_TCAM:
            for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, DsLtidSelectTcamMem_t) / SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM ) / 16; i++)
            {
                index = i*SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, 0));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, 0));

                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_ltidselect_tcam_result(lchip, index, err_mem_id));
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_TIDSELECT_REQ_MEM));
            }
            break;
         case SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM:
           for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, EgrSclHashTcamMem_t) / SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM ); i++)
            {
                index = (i*SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM ) % SYS_USW_DIAG_BIST_RAM_SZ_256;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, i*SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, i*SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM));

                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_egrsclhash_tcam_result(lchip, index, type, err_mem_id));
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_EGRSCLHASH_REQ_MEM));
            }
            break;

       case SYS_USW_DIAG_BIST_EGRACL_TCAM:
            for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, EgressAclTcamTcamMem_t) / SYS_USW_DIAG_BIST_EGRACL_REQ_MEM ); i++)
            {
                index = ( i*SYS_USW_DIAG_BIST_EGRACL_REQ_MEM ) % SYS_USW_DIAG_BIST_RAM_SZ_1K;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, i*SYS_USW_DIAG_BIST_EGRACL_REQ_MEM));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, i*SYS_USW_DIAG_BIST_EGRACL_REQ_MEM));

                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_egracl_tcam_result(lchip, index, err_mem_id));
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_EGRACL_REQ_MEM));
            }
            break;
        case SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM:
           for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip,  IpeHdrAdjRouterMacTcamMem_t) / SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM ); i++)
           {
               index = i*SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM;
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, 0));
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, 0));

               if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
               {
                   CTC_ERROR_RETURN(_sys_usw_diag_bist_ipehdrotemac_tcam_result(lchip, index, err_mem_id));
               }
               CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_REQ_MEM));
           }
           break;
        case SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM:
           for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, IpeHdrAdjUdfTcamMem_t) / SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM ); i++)
           {
               index = i*SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM;
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, 0));
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, 0));

               if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
               {
                   CTC_ERROR_RETURN(_sys_usw_diag_bist_ipehdudf_tcam_result(lchip, index, err_mem_id));
               }
               CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_IPEHDRADJUDF_REQ_MEM));
           }
           break;
        case SYS_USW_DIAG_BIST_PROGRAMACL_TCAM:
           for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, ProgramAclTcamMem_t) / SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM ); i++)
           {
               index = ( i*SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM ) % SYS_USW_DIAG_BIST_RAM_SZ_2K;
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, i*SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM));
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, i*SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM));

               if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
               {
                   CTC_ERROR_RETURN(_sys_usw_diag_bist_progrmacl_tcam_result(lchip, index, err_mem_id));
               }
               CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_PROGRAMACL_REQ_MEM));
           }
           break;
       case SYS_USW_DIAG_BIST_USERIDHASH_TCAM:
           for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip, UserIdHashTcamMem_t) / SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM ); i++)
           {
               index = ( i*SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM ) % SYS_USW_DIAG_BIST_RAM_SZ_512;
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, i*SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM));
               CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, i*SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM));

               if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
               {
                   CTC_ERROR_RETURN(_sys_usw_diag_bist_useridhash_tcam_result(lchip, index, err_mem_id));
               }
               CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_USERIDHASH_REQ_MEM));
           }
           break;
        case SYS_USW_DIAG_BIST_USERID_TCAM:
            for (i = 0; i < ( DRV_TABLE_MAX_INDEX(lchip,  UserIdTcamMem_t) / SYS_USW_DIAG_BIST_USERID_REQ_MEM ); i++)
            {
                index = ( i*SYS_USW_DIAG_BIST_USERID_REQ_MEM ) % SYS_USW_DIAG_BIST_RAM_SZ_1K;
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 0, i*SYS_USW_DIAG_BIST_USERID_REQ_MEM));
                CTC_ERROR_RETURN(_sys_usw_diag_bist_trigger(lchip, type, 1, i*SYS_USW_DIAG_BIST_USERID_REQ_MEM));

                if (CTC_E_NONE == _sys_usw_diag_bist_done(lchip, type))
                {
                    CTC_ERROR_RETURN(_sys_usw_diag_bist_userid_tcam_result(lchip, index, err_mem_id));
                }
                CTC_ERROR_RETURN(_sys_usw_diag_bist_mem_delete(lchip, type, i*SYS_USW_DIAG_BIST_USERID_REQ_MEM));
            }
            break;

        default:
            break;
    }
    return ret;
}
/*Rtl bug bistdone cannot be set*/
int32
_sys_tsingma_diag_bist_sram(uint8 lchip, uint8* err_mem_id)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 done = 0;
    uint8  wait_cnt = 0;
    sysMabistGo_m     sysbistgo;
    field_val = 0;
    cmd = DRV_IOW(SupIntrCtl_t, SupIntrCtl_interruptEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val);
    sal_memset(&sysbistgo, 0 , sizeof(sysMabistGo_m));
    cmd = DRV_IOW(sysMabistGo_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &sysbistgo);

    SetsysMabistGo(V,cfgBistRun_f, &sysbistgo, 1);
    DRV_IOCTL(lchip, 0, cmd, &sysbistgo);
    cmd = DRV_IOR(sysMabistDone_t, sysMabistDone_sfpReadyDbgSync_f);
    while (1)
    {
        DRV_FIELD_IOCTL(lchip, 0, cmd, &done);
        if (0xFFFF9 == done)
        {
            cmd = DRV_IOR(sysMabistFail_t, sysMabistFail_sfpFailDbgSync_f);
            DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val);
            *err_mem_id = field_val ? 0xff : 0;
            return CTC_E_NONE;
        }
        else
        {
            wait_cnt++;
            if (50 == wait_cnt)
            {
                *err_mem_id = 0xff;
                return CTC_E_HW_TIME_OUT;
            }
            sal_task_sleep(1);
        }
    }
    return ret;
}
int32
_sys_usw_diag_bist_sram(uint8 lchip, uint8* err_mem_id)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 done = 0;
    uint8  wait_cnt = 0;
    sysMabistGo_m     sysbistgo;
    field_val = 0;

    cmd = DRV_IOW(SupIntrCtl_t, SupIntrCtl_interruptEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val);

    sal_memset(&sysbistgo, 0 , sizeof(sysMabistGo_m));
    cmd = DRV_IOW(sysMabistGo_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &sysbistgo);

    SetsysMabistGo(V,cfgBistRun_f, &sysbistgo, 1);
    cmd = DRV_IOW(sysMabistGo_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &sysbistgo);

    cmd = DRV_IOR(sysMabistDone_t, sysMabistDone_bistDone_f);
    while (1)
    {

        DRV_FIELD_IOCTL(lchip, 0, cmd, &done);
        if (done)
        {
            cmd = DRV_IOR(sysMabistFail_t, sysMabistFail_sfpFailDbgSync_f);
            DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val);
            *err_mem_id = field_val? 0xff: 0;
            return CTC_E_NONE;
        }
        else
        {
            wait_cnt++;
            if (50 == wait_cnt)
            {
                *err_mem_id = 0xff;
                SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "SRAM BIST OUT OF TIME!\n");
                return CTC_E_HW_TIME_OUT;
            }
            sal_task_sleep(1);
        }
    }
    sal_memset(&sysbistgo, 0 , sizeof(sysMabistGo_m));
    cmd = DRV_IOW(sysMabistGo_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &sysbistgo);
    return ret;
}

#define ______INTERNAL_API______

int32
sys_usw_diag_drop_pkt_sync(ctc_pkt_rx_t* p_pkt_rx)
{
    int32 ret = CTC_E_NONE;
    uint8 lchip = 0;
    CTC_PTR_VALID_CHECK(p_pkt_rx);
    lchip = p_pkt_rx->lchip;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    DIAG_LOCK;
    ret = _sys_usw_diag_drop_pkt_sync(lchip, p_pkt_rx);
    DIAG_UNLOCK;
    return ret;
}
int32
_sys_usw_diag_mem_bist(uint8 lchip, uint8 mem_type, uint8* err_mem_id)
{
    switch (mem_type)
    {
        case SYS_USW_DIAG_BIST_FLOW_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_flow_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_LPM_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_LPM_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_lpm_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_LPM_TCAM0, err_mem_id));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_LPM_TCAM1, err_mem_id));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_LPM_TCAM2, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_CID_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_CID_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cid_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_CID_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_ENQUEUE_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_ENQUEUE_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_enqueue_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_ENQUEUE_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_TIDSELECT_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_TIDSELECT_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_LtidSelect_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_TIDSELECT_TCAM, err_mem_id));
            break;

        case SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_egrsclhash_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM, err_mem_id));
            break;

        case SYS_USW_DIAG_BIST_EGRACL_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_EGRACL_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_egracl_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_EGRACL_TCAM, err_mem_id));
            break;

       case SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_ipehdradjrmac_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM, err_mem_id));
            break;

       case SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_ipehdrudf_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM, err_mem_id));
            break;

       case SYS_USW_DIAG_BIST_PROGRAMACL_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_PROGRAMACL_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_programacl_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_PROGRAMACL_TCAM, err_mem_id));
            break;

        case SYS_USW_DIAG_BIST_USERIDHASH_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_USERIDHASH_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_useridhash_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_USERIDHASH_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_USERID_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_USERID_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_userid_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_USERID_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM, 0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_igs_programacl_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM, 0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_egs_programacl_tcam_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM, 0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_egs_program_tcam_ltid_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_tcam_prepare(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM,0));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_igs_program_tcam_ltid_req_prepare(lchip));
            CTC_ERROR_RETURN(_sys_usw_diag_bist_cmp_and_result(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM, err_mem_id));
            break;
        case SYS_USW_DIAG_BIST_SRAM:
            CTC_ERROR_RETURN(_sys_usw_diag_bist_sram(lchip, err_mem_id));
            break;
        default:
        return CTC_E_NONE;
    }

    return CTC_E_NONE;
}

#define ______SYS_API______
int32
sys_usw_diag_tcam_mbist_api(uint8 lchip, uint8* err_mem_id, uint8* err_cnt)
{
    int32 ret;

    if (SDK_WORK_PLATFORM == 1)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not support in UML!\n");
        return CTC_E_NOT_SUPPORT;
    }
    if (!DRV_IS_TSINGMA(lchip))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not support!\n");
        return CTC_E_NOT_SUPPORT;
    }

    CTC_PTR_VALID_CHECK(err_mem_id);
    CTC_PTR_VALID_CHECK(err_cnt);

    DIAG_LOCK;
    *err_cnt = 0;
    ret = (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_LPM_TCAM, err_mem_id, err_cnt));
    ret = ret ? ret : (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_CID_TCAM, err_mem_id, err_cnt));
    ret = ret ? ret : (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM, err_mem_id, err_cnt));
    ret = ret ? ret : (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_ENQUEUE_TCAM, err_mem_id, err_cnt));
    DIAG_UNLOCK;
    return ret;
}
int32
sys_usw_diag_tcam_function_bist_api(uint8 lchip, uint8 error_mem_id,
                                                           uint16* err_entry_cnt,
                                                            sys_diag_tcam_bmp* p_bmp)
{
    int32 ret = CTC_E_NONE;
    uint8 pattern;
    uint8 mem_type;
    LpmTcamCtl_m old_lpm_tcam_ctl;
    LpmTcamCtl_m lpm_tcam_ctl;
    uint32 cmd;

    SYS_USW_DIAG_INIT_CHECK(lchip);
    if (SDK_WORK_PLATFORM == 1)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not support in UML!\n");
        return CTC_E_NOT_SUPPORT;
    }
    if (!DRV_IS_TSINGMA(lchip))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not support!\n");
        return CTC_E_NOT_SUPPORT;
    }

    CTC_PTR_VALID_CHECK(err_entry_cnt);
    CTC_PTR_VALID_CHECK(p_bmp);
    *err_entry_cnt = 0;
    sal_memset(p_bmp, 0, sizeof(sys_diag_tcam_bmp));

    if(DRV_FTM_TCAM_KEY0 <= error_mem_id && error_mem_id < (DRV_FTM_TCAM_KEY0 + DRV_CONST(DRV_MAX_NOR_TCAM_NUM)))
    {
        mem_type = SYS_USW_DIAG_BIST_FLOW_TCAM;
    }
    else if(DRV_FTM_LPM_TCAM_KEY0 <= error_mem_id && error_mem_id < (DRV_FTM_LPM_TCAM_KEY0 + DRV_CONST(DRV_MAX_LPM_TCAM_NUM)))
    {
        mem_type = SYS_USW_DIAG_BIST_LPM_TCAM;
    }
    else if(DRV_FTM_QUEUE_TCAM == error_mem_id)
    {
        mem_type = SYS_USW_DIAG_BIST_ENQUEUE_TCAM;
    }
    else if(DRV_FTM_CID_TCAM == error_mem_id)
    {
        mem_type = SYS_USW_DIAG_BIST_CID_TCAM;
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }
    cmd = DRV_IOR(LpmTcamCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &old_lpm_tcam_ctl));
    /*Due to Rtl restricitions,lpm tcam can only take effect in nat mode*/
    sal_memset(&lpm_tcam_ctl, 0, sizeof(lpm_tcam_ctl));
    SetLpmTcamCtl(V, natTcamLookupEn_f, &lpm_tcam_ctl, 1);
    SetLpmTcamCtl(V, privatePublicLookupMode_f, &lpm_tcam_ctl, 6);
    cmd = DRV_IOW(LpmTcamCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &lpm_tcam_ctl);
    
    DIAG_LOCK;
    for(pattern=0; pattern < SYS_USW_DIAG_PATTERN_NUM; pattern++)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Test pattern [%u]!!!!!\n", pattern);
        ret = ret ? ret : (_sys_tm_diag_tcam_function_bist(lchip, mem_type, pattern, error_mem_id, err_entry_cnt, p_bmp));
    }
    DIAG_UNLOCK;

    cmd = DRV_IOW(LpmTcamCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &old_lpm_tcam_ctl);
    return ret;
}

int32
sys_usw_diag_mem_bist(uint8 lchip, ctc_diag_bist_mem_type_t mem_type, uint8* err_mem_id)
{
    int32 ret = CTC_E_NONE;
    LpmTcamCtl_m old_lpm_tcam_ctl;
    LpmTcamCtl_m lpm_tcam_ctl;
    uint32 cmd;

    SYS_USW_DIAG_INIT_CHECK(lchip);
    if (SDK_WORK_PLATFORM == 1)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not support in UML!\n");
        return CTC_E_NOT_SUPPORT;
    }
    if(DRV_IS_TSINGMA(lchip) && ((mem_type == CTC_DIAG_BIST_TYPE_TCAM) || (mem_type == CTC_DIAG_BIST_TYPE_ALL)))
    {
        uint8 error_cnt;
        uint8 error_mem_array[32] = {0};
        ret = (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_LPM_TCAM, error_mem_array, &error_cnt));
        ret = ret ? ret : (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_CID_TCAM, error_mem_array, &error_cnt));
        ret = ret ? ret : (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_FLOW_TCAM, error_mem_array, &error_cnt));
        ret = ret ? ret : (_sys_usw_diag_tcam_mbist(lchip, SYS_USW_DIAG_BIST_ENQUEUE_TCAM, error_mem_array, &error_cnt));
        *err_mem_id = error_mem_array[0];
    }
    else if ((mem_type == CTC_DIAG_BIST_TYPE_TCAM) || (mem_type == CTC_DIAG_BIST_TYPE_ALL))
    {
        cmd = DRV_IOR(LpmTcamCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &old_lpm_tcam_ctl));

        /*Due to Rtl restricitions,lpm tcam can only take effect in nat mode*/
        sal_memset(&lpm_tcam_ctl, 0, sizeof(lpm_tcam_ctl));
        SetLpmTcamCtl(V, natTcamLookupEn_f, &lpm_tcam_ctl, 1);
        SetLpmTcamCtl(V, privatePublicLookupMode_f, &lpm_tcam_ctl, 6);
        cmd = DRV_IOW(LpmTcamCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &lpm_tcam_ctl);
        ret =  _sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_LPM_TCAM, err_mem_id);
        ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_CID_TCAM, err_mem_id));
   
        if(DRV_FROM_AT(lchip))
        {
            ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM, err_mem_id));
            ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM, err_mem_id));
            /*-ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM, err_mem_id));   TODO
            -ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM, err_mem_id));*/
        }
        else
        {
            /* TMM */
            ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_TIDSELECT_TCAM, err_mem_id));
            ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_PROGRAMACL_TCAM, err_mem_id));
            ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_EGRACL_TCAM, err_mem_id));  
        }

        ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM, err_mem_id));
        ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM, err_mem_id));
        ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM, err_mem_id));
        ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_USERIDHASH_TCAM, err_mem_id));
        ret = ret ? ret : (_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_USERID_TCAM, err_mem_id));

        /*reset tcam*/
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_LPM_TCAM);
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_CID_TCAM);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM0, 0, 0);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM1, 0, 0);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_LPM_TCAM2, 0, 0);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_CID_TCAM, 0, 0);
  
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM);
       
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM);
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM);
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_USERIDHASH_TCAM);
        _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_USERID_TCAM);

        if(DRV_FROM_AT(lchip))
        {
            _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_LTID_TCAM, 0, 0);
            _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_LTID_TCAM, 0, 0);
            /*_sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_IGS_PROGRAMACL_TCAM, 0, 0);
            _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_EGS_PROGRAMACL_TCAM, 0, 0);*/
        }
        else
        {   _sys_usw_diag_bist_reset_tcam_valid_bit(lchip,SYS_USW_DIAG_BIST_EGRACL_TCAM);
            _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_TIDSELECT_TCAM, 0, 0);
            _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_PROGRAMACL_TCAM, 0, 0);
            _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_EGRACL_TCAM, 0, 0);
        }
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_EGRSCLHASH_TCAM, 0, 0);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_IPEHDRADJROUTERMAC_TCAM, 0, 0);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_IPEHDRADJUDF_TCAM, 0, 0);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_USERIDHASH_TCAM, 0, 0);
        _sys_usw_diag_bist_trigger(lchip, SYS_USW_DIAG_BIST_USERID_TCAM, 0, 0);
         

        cmd = DRV_IOW(LpmTcamCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &old_lpm_tcam_ctl);
    }
    if ((mem_type == CTC_DIAG_BIST_TYPE_SRAM) || (mem_type == CTC_DIAG_BIST_TYPE_ALL))
    {
      
        if(DRV_FROM_TMM(lchip))
        {
            if (MCHIP_DIAG(lchip)->diag_mem_bist)
            {
                CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->diag_mem_bist(lchip, err_mem_id));
            }
            else
            {
                CTC_ERROR_RETURN(_sys_usw_diag_mem_bist(lchip, SYS_USW_DIAG_BIST_SRAM, err_mem_id));
            }
        }
        else
        {
            CTC_ERROR_RETURN(_sys_tsingma_diag_bist_sram(lchip, err_mem_id));
        }

    }
    return ret;
}

int32
sys_usw_diag_pkt_trace_key_check_and_clear_rslt(uint8 lchip, ctc_diag_pkt_trace_t* p_trace)
{
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_trace);
    CTC_ERROR_RETURN(_sys_usw_diag_pkt_trace_watch_key_check(lchip, p_trace));
    if (MCHIP_DIAG(lchip)->pkt_trace_clear_rslt)
    {
        CTC_ERROR_RETURN(MCHIP_DIAG(lchip)->pkt_trace_clear_rslt(lchip, p_trace->watch_point));
    }

    return CTC_E_NONE;
}

int32
sys_usw_diag_trigger_pkt_trace(uint8 lchip, ctc_diag_pkt_trace_t* p_trace)
{
    int32 ret = CTC_E_NONE;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_trace);
    if (!DRV_FROM_AT(lchip))
    {
        CTC_ERROR_RETURN(_sys_usw_diag_pkt_trace_watch_key_check(lchip, p_trace));
    }
    DIAG_LOCK;
    ret = _sys_usw_diag_trigger_pkt_trace(lchip, p_trace);
    DIAG_UNLOCK;
    return ret;

}

int32
sys_usw_diag_get_pkt_trace(uint8 lchip, ctc_diag_pkt_trace_result_t* p_rslt, uint8 position)
{
    int32 ret = CTC_E_NONE;

    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_rslt);

    DIAG_LOCK;
    if (MCHIP_DIAG(lchip)->get_pkt_trace)
    {
        ret = MCHIP_DIAG(lchip)->get_pkt_trace(lchip, (void*)p_rslt, position);
    }
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_get_drop_reason(uint8 lchip, uint16 drop_reason)
{
    uint32 reason[10] = {0};
    CTC_MAX_VALUE_CHECK(drop_reason,CTC_DROP_MAX);
    if (MCHIP_DIAG(lchip)->map_drop_reason_ctc_to_sys)
    {
        MCHIP_DIAG(lchip)->map_drop_reason_ctc_to_sys(drop_reason, reason);
    }
    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", sys_usw_register_get_reason_desc(lchip, drop_reason));
    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-----------------------------------------------------------------------------------------------------------------------------\n");
    if (MCHIP_DIAG(lchip)->diag_get_drop_reason)
    {
        MCHIP_DIAG(lchip)->diag_get_drop_reason(lchip,reason);
    }
    SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-----------------------------------------------------------------------------------------------------------------------------\n");
    return 0;
}

int32
sys_usw_diag_get_drop_info(uint8 lchip, ctc_diag_drop_t* p_drop)
{
    int32 ret = CTC_E_NONE;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_drop);
    if(CTC_DIAG_DROP_OPER_TYPE_GET_DETAIL_INFO == p_drop->oper_type && 0 != p_drop->u.info.buffer_count)
    {
        CTC_PTR_VALID_CHECK(p_drop->u.info.buffer);
    }
    DIAG_LOCK;
    ret = _sys_usw_diag_get_drop_info(lchip, p_drop);
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_set_property(uint8 lchip, ctc_diag_property_t prop, void* p_value)
{
    int32 ret = CTC_E_NONE;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_value);
    if (prop >= CTC_DIAG_PROP_MAX)
    {
        return CTC_E_INVALID_PARAM;
    }

    if (prop == CTC_DIAG_PROP_DROP_PKT_CONFIG)
    {
        _sys_usw_diag_set_drop_pkt_cb(lchip, (ctc_diag_drop_pkt_config_t*)p_value);
    }
    DIAG_LOCK;
    ret = _sys_usw_diag_set_property(lchip, prop, p_value);
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_get_property(uint8 lchip, ctc_diag_property_t prop, void* p_value)
{
    int32 ret = CTC_E_NONE;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_value);
    if (prop >= CTC_DIAG_PROP_MAX)
    {
        return CTC_E_INVALID_PARAM;
    }
    DIAG_LOCK;
    ret = _sys_usw_diag_get_property(lchip, prop, p_value);
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_tbl_control(uint8 lchip, ctc_diag_tbl_t *p_para)
{
    int32 ret = CTC_E_NONE;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_para);
 //   CTC_PTR_VALID_CHECK(p_para->info);
    if (p_para->type >= CTC_DIAG_TBL_OP_MAX /*|| p_para->entry_num == 0 || sal_strlen(p_para->tbl_str) == 0*/)
    {
        return CTC_E_INVALID_PARAM;
    }
    DIAG_LOCK;
    ret = _sys_usw_diag_tbl_control(lchip, p_para);
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_set_lb_distribution(uint8 lchip, ctc_diag_lb_dist_t* p_para)
{
    int32 ret = CTC_E_NONE;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_para);
    DIAG_LOCK;
    ret = _sys_usw_diag_set_lb_distribution(lchip, p_para);
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_get_lb_distribution(uint8 lchip, ctc_diag_lb_dist_t* p_para)
{
    int32 ret = CTC_E_NONE;
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_para);
    CTC_PTR_VALID_CHECK(p_para->info);
    CTC_MIN_VALUE_CHECK(p_para->member_num, 1);
    DIAG_LOCK;
    ret = _sys_usw_diag_get_lb_distribution(lchip, p_para);
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_get_mem_usage(uint8 lchip, ctc_diag_mem_usage_t* p_para)
{
    int32 ret = CTC_E_NONE;
    uint32 total_num = 0;
    uint32 used_num = 0;
    uint8 loop = 0;
    uint8 loop1 = 0;
    uint8 loop_num[4] = {1,8,3,4};
    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_para);
    DIAG_LOCK;
    if(p_para->type == CTC_DIAG_TYPE_SRAM_ALL)
    {
        for(loop = CTC_DIAG_TYPE_SRAM_MAC;loop < CTC_DIAG_TYPE_SRAM_ALL; loop ++)
        {
            p_para->type = loop;
            p_para->total_num = 0;
            p_para->used_num = 0;
            p_para->sub_type = 0;
            _sys_usw_diag_get_mem_usage(lchip, p_para);
            total_num += p_para->total_num;
            used_num += p_para->used_num;
        }
        p_para->total_num = total_num;
        p_para->used_num = used_num;
        p_para->type = CTC_DIAG_TYPE_SRAM_ALL;
    }
    else if(p_para->type == CTC_DIAG_TYPE_TCAM_ALL)
    {
        for(loop = CTC_DIAG_TYPE_TCAM_LPM;loop < CTC_DIAG_TYPE_TCAM_ALL; loop ++)
        {
            for(loop1 = 0; loop1 < loop_num[loop-CTC_DIAG_TYPE_TCAM_LPM]; loop1 ++)
            {
                p_para->type = loop;
                p_para->sub_type = loop1;
                p_para->total_num = 0;
                p_para->used_num = 0;
                _sys_usw_diag_get_mem_usage(lchip, p_para);
                total_num += p_para->total_num;
                used_num += p_para->used_num;
            }
        }
        p_para->total_num = total_num;
        p_para->used_num = used_num;
        p_para->sub_type = 0;
        p_para->type = CTC_DIAG_TYPE_TCAM_ALL;
    }
    else
    {
        ret = _sys_usw_diag_get_mem_usage(lchip, p_para);
    }
    DIAG_UNLOCK;
    return ret;
}

STATIC int32
_sys_usw_diag_get_queue_depth_io(uint8 lchip, sys_traverse_t* data)
{
    ctc_diag_queue_depth_t* p_queue_query = (ctc_diag_queue_depth_t*)data->data;
    ds_t ds;
    uint32 tbl_id = 0;
    uint32 cmd = 0;
    uint32 depth[2] = {0};
    uint16 start_pos = p_queue_query->valid_count;
    uint16 count = 0;
    uint8 is_mc = (data->value3 >> 30) & 0x1;
    uint8 pp_id = data->value2 >> 20;
    uint8 dp_id = (data->value2 >> 16) & 0x1;
    uint8 is_dma = data->value3 >> 31;
    uint8 ofst = (data->value3 >> 16) & 0x1;
    uint8 loop = 0;
    switch (is_mc)
    {
        case 0 :
            tbl_id = is_dma ? DsErmDmaCntUc_t : DsErmQueueCntUc_t;
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(SYS_PP_BASE(lchip) + pp_id, data->value4, DRV_CMD_DP_EN(cmd, dp_id), &ds));
            depth[0] = GetDsErmQueueCntUc(V, queueCnt_f, &ds);
            if (SYS_VCHIP_DUAL_CORE_MODE(lchip))
            {
                uint8 _dual_core_lchip = 0;
                SYS_VCHIP_DUAL_CORE_LCHIP_MAP(SYS_PP_BASE(lchip) + pp_id, _dual_core_lchip);
                CTC_ERROR_RETURN(DRV_IOCTL(_dual_core_lchip, data->value4 + DRV_TABLE_MAX_INDEX(lchip, tbl_id) / 2, DRV_CMD_DP_EN(cmd, dp_id), &ds));
                depth[1] = GetDsErmQueueCntUc(V, queueCnt_f, &ds);
            }
            break;
        default :
            tbl_id = is_dma ? DsErmDmaCntMc_t : DsErmQueueCntMc_t;
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(SYS_PP_BASE(lchip) + pp_id, data->value4, DRV_CMD_PP_EN(cmd), &ds));
            depth[0] = GetDsErmQueueCntMc(V, g_0_queueCnt_f, &ds);
            if (SYS_VCHIP_DUAL_CORE_MODE(lchip) && !is_dma)
            {
                uint8 _dual_core_lchip = 0;
                SYS_VCHIP_DUAL_CORE_LCHIP_MAP(SYS_PP_BASE(lchip) + pp_id, _dual_core_lchip);
                CTC_ERROR_RETURN(DRV_IOCTL(_dual_core_lchip, data->value4 + DRV_TABLE_MAX_INDEX(lchip, tbl_id) / 2, DRV_CMD_PP_EN(cmd), &ds));
                depth[1] = GetDsErmQueueCntMc(V, g_0_queueCnt_f, &ds);
            }
        break;
    }
    for (loop = 0; loop < 2; loop++)
    {
        if (0==depth[loop])
        {
            continue;
        }
        if ((start_pos + count) < p_queue_query->buffer_count)
        {
            (p_queue_query->p_queue_depth_info + start_pos + count)->queue_id = data->value1;
            (p_queue_query->p_queue_depth_info + start_pos + count)->queue_depth = depth[loop];
            (p_queue_query->p_queue_depth_info + start_pos + count)->pp_id = pp_id < SYS_CORE_PP_NUM(0) ?  loop * SYS_CORE_PP_NUM(0) : !loop * SYS_CORE_PP_NUM(0);
            (p_queue_query->p_queue_depth_info + start_pos + count)->class_prio = ofst;
        }
        count++;
    }
    p_queue_query->valid_count += count;
    return CTC_E_NONE;
}

int32
sys_usw_diag_get_queue_depth(uint8 lchip, ctc_diag_queue_depth_t* p_queue_query)
{
    uint16 idx = 0;
    uint16 entry_num = 0;
    uint32 cmd = 0;
    uint16 buffer_index = 0;
    uint32 value = 0;
    int32 ret = CTC_E_NONE;

    SYS_USW_DIAG_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_queue_query);
    CTC_PTR_VALID_CHECK(p_queue_query->p_queue_depth_info);

    DIAG_LOCK;
    if (DRV_FROM_AT(lchip))
    {
        ret = sys_usw_queue_traverse_queue_node(lchip, 0xFFFF, _sys_usw_diag_get_queue_depth_io, p_queue_query);
        DIAG_UNLOCK;
        return ret;
    }
    entry_num = DRV_TABLE_MAX_INDEX(lchip, DsErmQueueCnt_t);
    cmd = DRV_IOR(DsErmQueueCnt_t, DsErmQueueCnt_queueCnt_f);
    for (idx = 0; idx < entry_num; idx++)
    {
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, idx, cmd, &value), ret, done);
        if (0 != value)
        {
            if (buffer_index < p_queue_query->buffer_count)
            {
                (p_queue_query->p_queue_depth_info + buffer_index)->queue_id = idx;
                (p_queue_query->p_queue_depth_info + buffer_index)->queue_depth = value;
            }
            buffer_index++;
        }
    }
    p_queue_query->valid_count = buffer_index;

    done:
    DIAG_UNLOCK;
    return ret;
}

int32
sys_usw_diag_get_lb_hash(uint8 lchip, ctc_field_key_t* p_field_list, uint32 field_cnt, ctc_diag_lb_hash_t* p_rslt)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_field_list);
    CTC_PTR_VALID_CHECK(p_rslt);
    CTC_VALUE_RANGE_CHECK(field_cnt, 1, CTC_FIELD_KEY_NUM);
    SYS_USW_DIAG_INIT_CHECK(lchip);
    DIAG_LOCK;
    if (MCHIP_DIAG(lchip)->get_lb_hash)
    {
        ret = (MCHIP_DIAG(lchip)->get_lb_hash(lchip, p_field_list, field_cnt, p_rslt));
    }
    DIAG_UNLOCK;

    return ret;
}

int32
sys_usw_diag_init(uint8 lchip, void* init_cfg)
{
    int32 ret = CTC_E_NONE;

    if (p_usw_diag_master[lchip])
    {
        return CTC_E_NONE;
    }
    SYS_VCHIP_MASTER_INIT(lchip, p_usw_diag_master, CTC_FEATURE_DIAG);

    p_usw_diag_master[lchip] = (sys_usw_diag_t*)mem_malloc(MEM_DIAG_MODULE, sizeof(sys_usw_diag_t));
    if ( NULL == p_usw_diag_master[lchip] )
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Diag Init Error. No Memory! \n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_usw_diag_master[lchip], 0, sizeof(sys_usw_diag_t));

    ret = sal_mutex_create(&(p_usw_diag_master[lchip]->diag_mutex));
    if (ret || !(p_usw_diag_master[lchip]->diag_mutex))
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No resource in ASIC. Mutex Create Failed! \n");
        ret = CTC_E_NO_RESOURCE;
        goto error_back;
    }
    p_usw_diag_master[lchip]->drop_hash = ctc_hash_create(MCHIP_CAP(SYS_CAP_PHY_PORT_NUM_PER_SLICE), CTC_HASH_16_BLOCK_SIZE,
                                        (hash_key_fn)_sys_usw_diag_drop_hash_make,
                                        (hash_cmp_fn)_sys_usw_diag_drop_hash_cmp);
    if (NULL == p_usw_diag_master[lchip]->drop_hash)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Diag Init Error. No Memory! \n");
        ret = CTC_E_NO_MEMORY;
        goto error_back;
    }

    p_usw_diag_master[lchip]->lb_dist = ctc_hash_create((MCHIP_CAP(SYS_CAP_LINKAGG_GROUP_NUM)+MCHIP_CAP(SYS_CAP_NH_ECMP_GROUP_ID_NUM)+1)/CTC_HASH_32_BLOCK_SIZE , CTC_HASH_32_BLOCK_SIZE,
                                        (hash_key_fn)_sys_usw_diag_dist_hash_make,
                                        (hash_cmp_fn)_sys_usw_diag_dist_hash_cmp);
    if (NULL == p_usw_diag_master[lchip]->lb_dist)
    {
        SYS_DIAG_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Diag Init Error. No Memory! \n");
        ret = CTC_E_NO_MEMORY;
        goto error_back;
    }

    p_usw_diag_master[lchip]->drop_pkt_overwrite = 1;
    p_usw_diag_master[lchip]->drop_pkt_hash_len = 64;
    p_usw_diag_master[lchip]->drop_pkt_store_cnt = 128;
    p_usw_diag_master[lchip]->drop_pkt_store_len = 256;

    CTC_ERROR_RETURN(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_DIAG, _sys_usw_diag_dump_db));
    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_DIAG);
    return CTC_E_NONE;

error_back:
    sys_usw_diag_deinit(lchip);
    return ret;
}


int32
sys_usw_diag_deinit(uint8 lchip)
{
    LCHIP_CHECK(lchip);
    if (NULL == p_usw_diag_master[lchip])
    {
        return CTC_E_NONE;
    }
    SYS_VCHIP_MASTER_DEINIT(lchip, p_usw_diag_master, CTC_FEATURE_DIAG);

    if (p_usw_diag_master[lchip]->drop_hash)
    {
        ctc_hash_free2(p_usw_diag_master[lchip]->drop_hash, (hash_traversal_fn)_sys_usw_diag_free_drop_hash_data, NULL);
    }
    if (p_usw_diag_master[lchip]->lb_dist)
    {
        ctc_hash_free2(p_usw_diag_master[lchip]->lb_dist, (hash_traversal_fn)_sys_usw_diag_free_dist_hash_data, NULL);
    }
    if (p_usw_diag_master[lchip]->diag_mutex)
    {
        sal_mutex_destroy(p_usw_diag_master[lchip]->diag_mutex);
    }
    _sys_usw_diag_drop_pkt_clear_buf(lchip);
    sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_DIAG, NULL);
    ctc_slist_free(p_usw_diag_master[lchip]->drop_pkt_list);
    mem_free(p_usw_diag_master[lchip]);
    return CTC_E_NONE;
}
#endif

